动态方法决议 和 消息转发
2014-06-05 13:11
267 查看
假设我们在 Objective C 中向一个对象发送它无法处理的消息,会出现什么情况呢?我们知道发送消息是通过
objc_send(id, SEL, ...) 来实现的,它会首先在对象的类对象的 cache,method list 以及父类对象的 cache, method list 中依次查找 SEL 相应的 IMP;这个是须要对类对象的结构熟悉,不清楚的能够參考我的下一篇文章《object-c
类结构解析》,假设没有找到且实现了动态方法决议机制就会进行决议,假设没有实现动态方法决议机制或决议失败且实现了消息转发机制就会进入消息转发流程,否则程序
crash。也就是说假设同一时候提供了动态方法决议和消息转发,那么动态方法决议先于消息转发,仅仅有当动态方法决议依旧无法正确决议 selector 的实现,才会尝试进行消息转发。
1. 什么是动态方法决议
Objective C 提供了一种名为动态方法决议的手段,使得我们能够在执行时动态地为一个 selector 提供实现。我们仅仅要实现 +resolveInstanceMethod: 或 +resolveClassMethod:
方法,并在当中为指定的 selector 提供实现就可以(通过调用执行时函数 class_addMethod 来加入�)。这两个方法都是 NSObject 中的类方法,其原型为:
2.消息转发
实现下面这两个方法
从上面的演示样例演示能够看出,动态方法决议是先于消息转发的。
假设向一个 Objective C 对象对象发送它无法处理的消息(selector),那么编译器会依照例如以下次序进行处理:
1,首先看是否为该 selector 提供了动态方法决议机制,假设提供了则转到 2;假设没有提供则转到 3;
2,假设动态方法决议真正为该 selector 提供了实现,那么就调用该实现,完毕消息发送流程,消息转发就不会进行了;假设没有提供,则转到 3;
3,其次看是否为该 selector 提供了消息转发机制,假设提供了消息了则进行消息转发,此时,不管消息转发是如何实现的,程序均不会 crash。(由于消息调用的控制权全然交给消息转发机制处理,即使消息转发并没有做不论什么事情,执行也不会有错误,编译器更不会有错误提示。);假设没提供消息转发机制,则转到
4;
4,执行报错:无法识别的 selector,程序 crash;
參考:
/article/4926774.html
/article/5675696.html
objc_send(id, SEL, ...) 来实现的,它会首先在对象的类对象的 cache,method list 以及父类对象的 cache, method list 中依次查找 SEL 相应的 IMP;这个是须要对类对象的结构熟悉,不清楚的能够參考我的下一篇文章《object-c
类结构解析》,假设没有找到且实现了动态方法决议机制就会进行决议,假设没有实现动态方法决议机制或决议失败且实现了消息转发机制就会进入消息转发流程,否则程序
crash。也就是说假设同一时候提供了动态方法决议和消息转发,那么动态方法决议先于消息转发,仅仅有当动态方法决议依旧无法正确决议 selector 的实现,才会尝试进行消息转发。
1. 什么是动态方法决议
Objective C 提供了一种名为动态方法决议的手段,使得我们能够在执行时动态地为一个 selector 提供实现。我们仅仅要实现 +resolveInstanceMethod: 或 +resolveClassMethod:
方法,并在当中为指定的 selector 提供实现就可以(通过调用执行时函数 class_addMethod 来加入�)。这两个方法都是 NSObject 中的类方法,其原型为:
+ (BOOL)resolveClassMethod:(SEL)name; + (BOOL)resolveInstanceMethod:(SEL)name;
2.消息转发
实现下面这两个方法
- (void)forwardInvocation:(NSInvocation *)anInvocation { SEL name = [anInvocation selector]; NSLog(@" >> forwardInvocation for selector %@", NSStringFromSelector(name)); Proxy * proxy = [[[Proxy alloc] init] autorelease]; if ([proxy respondsToSelector:name]) { [anInvocation invokeWithTarget:proxy]; } else { [super forwardInvocation:anInvocation]; } } - (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector { return [Proxy instanceMethodSignatureForSelector:aSelector]; }
总结
从上面的演示样例演示能够看出,动态方法决议是先于消息转发的。假设向一个 Objective C 对象对象发送它无法处理的消息(selector),那么编译器会依照例如以下次序进行处理:
1,首先看是否为该 selector 提供了动态方法决议机制,假设提供了则转到 2;假设没有提供则转到 3;
2,假设动态方法决议真正为该 selector 提供了实现,那么就调用该实现,完毕消息发送流程,消息转发就不会进行了;假设没有提供,则转到 3;
3,其次看是否为该 selector 提供了消息转发机制,假设提供了消息了则进行消息转发,此时,不管消息转发是如何实现的,程序均不会 crash。(由于消息调用的控制权全然交给消息转发机制处理,即使消息转发并没有做不论什么事情,执行也不会有错误,编译器更不会有错误提示。);假设没提供消息转发机制,则转到
4;
4,执行报错:无法识别的 selector,程序 crash;
參考:
/article/4926774.html
/article/5675696.html
相关文章推荐
- 动态方法决议 和 消息转发
- cocoa动态方法决议及消息转发
- 动态方法决议与消息转发
- cocoa动态方法决议及消息转发
- iOS的动态创建实例方法和实现消息转发
- [深入浅出Cocoa]之消息(二)-详解动态方法决议(Dynamic Method Resolution)
- iOS消息机制--动态方法解析、消息转发机制
- runtime动态添加方法引出的消息转发
- [深入浅出Cocoa]之消息(二)-详解动态方法决议(Dynamic Method Resolution)
- [深入浅出Cocoa]之消息(二)-详解动态方法决议(Dynamic Method Resolution)
- 深入浅出Cocoa之消息(二)-详解动态方法决议(Dynamic Method Resolution) 【转】
- Runtime(二)动态添加方法以及消息转发机制
- ios底层开发消息机制(三)动态方法决议
- iOS开发------runtime之动态添加方法(动态决议,请求转发)
- [深入浅出Cocoa]之消息(二)-详解动态方法决议(Dynamic Method Resolution)
- runtime之动态添加方法(动态决议,请求转发)
- Effective Objective-C(第11-14条)动态绑定、objc_msgSend、消息转发机制
- Delphi之静态方法,虚方法virtual,动态dynamic,抽象abstract,消息
- 实现消息转发功能(调用非自己类方法)
- 动态改变窗口图标的方法 WM_SETICON消息