objc 消息转发

今天突然又兴趣看了下 NSObject的头文件,发现其中的消息转发机制还不甚了解,所以在 debug 调试了解之后,写下此文章留作记录

1 - (id)forwardingTargetForSelector:(SEL)aSelector;
2 - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector;
3 + (NSMethodSignature *)instanceMethodSignatureForSelector:(SEL)aSelector;
4 - (void)forwardInvocation:(NSInvocation *)anInvocation;
5 - (void)doesNotRecognizeSelector:(SEL)aSelector;
调用顺序如上面函数顺序

当使用如下函数调用

1 [someObj method1];//方式1
2 [someObj performSelector:@selector(method1)];//方式2
如果 someObj没有实现 method1函数

runtime 将会调用

1 - (id)forwardingTargetForSelector:(SEL)aSelector
2 {
3     if ([SomeObj respondsToSelector:aSelector]) {
4         return someObj;
5     }
6      
7     return nil;
8 }

如果 SomeObj 能够响应 aSelector,我们就将此消息转发到 someObj.

如果SomeObj 不能响应,函数返回了 nil

此时 runtime system将调用

1 - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
2 {
3     NSMethodSignature *signature = [super methodSignatureForSelector:aSelector];
4     if (signature == nil) {
5         signature = [OtherObj instanceMethodSignatureForSelector:aSelector];
6     }
7      
8     return signature;
9 }

如果父类没有实现此SEL,就询问 OtherObj 是否实现此 SEL

如果实现就返回NSMethodSignature

否则就返回 nil,此时 runtime system就会调用

1 - (void)doesNotRecognizeSelector:(SEL)aSelector
2 {
3     NSLog(@"%@ %@",NSStringFromClass(self.class),NSStringFromSelector(_cmd));
4 }
表示没有实现此函数,并抛出NSInvalidArgumentException  异常

可以在此函数中做程序最后的处理

说回去,如果OtherObj实现了此函数,则 runtime system 会调用

1 - (void)forwardInvocation:(NSInvocation *)anInvocation
2 {
3     if ([OtherObj instancesRespondToSelector:[anInvocation selector]])
4         [anInvocation invokeWithTarget:otherObj];
5     else
6         [super forwardInvocation:anInvocation];
7 }
这样写是为了让父类的转发不被覆盖,这里如果不调用

1 [anInvocation invokeWithTarget:otherObj];

将不会真正调用函数

到此,转发的方式与过程叙述完毕



转载:http://my.oschina.net/u/811205/blog/175537

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值