iOS之《Effective Objective-C 2.0》读书笔记(12)

第12条:理解消息转发机制

1.消息转发机制的作用
对象在接受到无法解读的消息时,会在编译时报警告,运行时直接崩溃,此方法可以给对象和消息更多的机会来完成成功的调用
2.消息转发流程

流程图

(1)动态方法解析:

+(BOOL)resolveInstanceMethod:(SEL)sel // 实例方法
+(BOOL)resolveClassMethod:(SEL)sel    // 类方法
  • 下列代码演示了如何用“resolveInstanceMethod:”来实现@dynamic属性:

id autoDictionaryGetter(id self, SEL _cmd);  
void autoDictionarySetter(id self, SEL _cmd, id value);  

+ (BOOL)resolveInstanceMethod:(SEL)selector {  
    NSString *selectorString = NSStringFromSelector(selector);  
    if ( /* selector is from a @dynamic property */ ) {  
        if ([selectorString hasPrefix:@"set"]) {  
            class_addMethod(self,  
                            selector,  
                            (IMP)autoDictionarySetter,  
                            "v@:@");  
        } else {  
            class_addMethod(self,  
                            selector,  
                            (IMP)autoDictionaryGetter,  
                            "@@:");  
        }  
        return YES;  
    }  
return [super resolveInstanceMethod:selector];  
} 

(2)备援接受者:运行期系统把消息转给其他接收者处理

- (id)forwardingTargetForSelector:(SEL)aSelector
{
    class *other = [class new];
    if ([other forwardingTargetForSelector:aSelector]) {
        return other;
    }else{
        return [super forwardingTargetForSelector:aSelector];
    }
}

(3)完整的消息转发:创建NSInvocation对象,把与尚未处理的那条消息有关的全部细节都封于其中。此对象包含选择子、目标target及参数。在触发NSInvocation对象时,消息派发系统会把消息指派给目标对象

  • TestModel
- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector {  
    if(aSelector == @selector(testMethod))  
    {  
        return [NSMethodSignature signatureWithObjCTypes:"v@:"];  
    }  
    return nil;  
}  

-(void)forwardInvocation:(NSInvocation *)anInvocation  
{  
    if (anInvocation.selector == @selector(testMethod))  
    {  
        TestModelHelper1 *h1 = [[TestModelHelper1 alloc] init];  
        TestModelHelper2 *h2 = [[TestModelHelper2 alloc] init];  
        [anInvocation invokeWithTarget:h1];  
        [anInvocation invokeWithTarget:h2];  
    }  
}  
  • TestModelHelper1
-(void)testMethod  
{  
    NSLog(@"i am TestModelHelper1");  
}  
  • TestModelHelper2
-(void)testMethod  
{  
    NSLog(@"i am TestModelHelper2");  
}  
  • 主调用类 : TestModel本身没有实现testMethod方法,但最终运行后,程序没有报错,且TestModelHelper1和TestModelHelper2的testMethod方法都被执行了
TestModel *model = [[TestModel alloc] init];  
[model testMethod];  

(4)消息未能处理:调用doesNotRecognizeSelector抛出异常

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值