objective-c 的消息转发

2017-03-26  本文已影响205人  幸运者_Lucky

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];
    }
// 这里可以转发若干个你想转发的对象
}
上一篇下一篇

猜你喜欢

热点阅读