美文网首页
objective-c 的消息转发

objective-c 的消息转发

作者: 幸运者_Lucky | 来源:发表于2017-03-26 01:55 被阅读205次

    objc 在执行一个方法的时候是如何判断一个方法是否存在的?

    1. 从本类和父类中查找.
    2. 检查是否动态添加方法.
    3. 查看是否存在快速消息转发.
    4. 查看标准消息转发.

    1-4是按照顺序进行的, 若在某个环节查到符合的方法, 下面的查找则终止.

    1. 我就不具体解释了.
    2. objc 是一门动态的语言, 它允许在运行时, 向一个类添加属性、方法等. class_addMethod、class_addIvar、class_addProperty、class_addProtocol. 具体使用就不介绍了. 需要重写 resolveInstanceMethod 方法, 在其中判断需要添加的方法, 使用class_addMethod来动态添加方法.
    +(BOOL)resolveInstanceMethod:(SEL)aSEL
    {
        if(aSEL == @selector(methodName)){
            class_addMethod(Class cls, SEL name, IMP imp, 
                                     const char *types) ;
            return YES;
        }
        return [super resolveInstanceMethod];
    }
    
    1. NSObject 提供快速消息转发方法, 只要重新
    - (id)forwardingTargetForSelector:(SEL)aSelector
    

    之后, 每次在父类本类中找不到, 并且没有找到动态添加方法, 则会走该方法, 你可以在这个方法中, return 目标对象, 则目标对象执行 aSelector. 如果没有重写标准消息转发, 并且 return nil, 则会报 unrecognized selector sent to instance 这个错误.

    - (id)forwardingTargetForSelector:(SEL)aSelector
    {
        Person *person = [[Person alloc]init];
        if ([person respondsToSelector:aSelector]) {
            return person;
        }
        return nil;
    }
    

    4.标准消息转发, 主要可以实现多对象同时转发

    // 生成一个方法, 并存入表中
    - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
    {
        NSMethodSignature* signature = [super methodSignatureForSelector:aSelector];
        if (!signature) {
            signature = [yourObj methodSignatureForSelector:aSelector];
        }
        return signature; // 将一个新签名的方法放入表中
    }
    
    // 实现动态添加方法, 并执行方法
    - (void)forwardInvocation:(NSInvocation *)anInvocation
    {
        SEL seletor = [anInvocation selector];
        if ([yourObj respondsToSelector:seletor]) {
            [anInvocation invokeWithTarget:yourObj];
        }
    // 这里可以转发若干个你想转发的对象
    }
    

    相关文章

      网友评论

          本文标题:objective-c 的消息转发

          本文链接:https://www.haomeiwen.com/subject/oyehottx.html