看了一下文章也進行了一些測試,關於消息轉發做一小節。
<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>