看了一下文章也进行了一些测试,关于消息转发做一小节。
<span style="font-size:14px;">- (id)forwardingTargetForSelector:(SEL)aSelector;
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector;
+ (NSMethodSignature *)instanceMethodSignatureForSelector:(SEL)aSelector;
- (void)forwardInvocation:(NSInvocation *)anInvocation;
- (void)doesNotRecognizeSelector:(SEL)aSelector;
</span>
调用方法:
[someObj method1];//方式1
[someObj performSelector:@selector(method1)];//方式2
如果 SomeObj没有实现 method1函数
runtime 将会调用
<span style="font-size:14px;">- (id)forwardingTargetForSelector:(SEL)aSelector
{
if ([SomeObj respondsToSelector:aSelector]) {
return SomeObj;
}
return nil;
}</span>
如果 SomeObj 能够响应 aSelector,我们就将此消息转发到 SomeObj.
如果SomeObj 不能响应,函数返回了 nil
此时 runtime system将调用
<span style="font-size:14px;">- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector
{
NSMethodSignature *signature = [super methodSignatureForSelector:aSelector];
if (signature == nil) {
signature = [OtherObj instanceMethodSignatureForSelector:aSelector];
}
return signature;</span><pre name="code" class="objc"><span style="font-size:14px;">}</span>
如果父类没有实现此SEL,就询问 OtherObj 是否实现此 SEL
如果实现就返回NSMethodSignature
否则就返回 nil,此时 runtime system就会调用
<span style="font-size:14px;">- (void)doesNotRecognizeSelector:(SEL)aSelector
{
NSLog(@"%@ %@",NSStringFromClass(self.class),NSStringFromSelector(_cmd));
}</span><span style="font-size: 11px;">
</span>
表示没有实现此函数,并抛出NSInvalidArgumentException 异常
可以在此函数中做程序最后的处理
说回去,如果OtherObj实现了此函数,则 runtime system 会调用
<span style="font-size:14px;">- (void)forwardInvocation:(NSInvocation *)anInvocation
{
if ([OtherObj instancesRespondToSelector:[anInvocation selector]])
[anInvocation invokeWithTarget:otherObj];
else
[super forwardInvocation:anInvocation];
}</span>