runtime淺談(三)消息轉發

看了一下文章也進行了一些測試,關於消息轉發做一小節。

<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>





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章