Runtime消息转发机制
来源:互联网 发布:智能音箱 知乎 编辑:程序博客网 时间:2024/05/16 15:11
@interface ViewController ()@property (nonatomic, copy) NSString *name;@property (nonatomic, copy) NSString *age;@end@implementation ViewController// 告诉编译器,不要生成set 和 get方法,但是调用get 和set也不会出错@dynamic name;- (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view, typically from a nib. }
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{ self.name = @"pangshishan";}
上述代码中中name是一个属性,在@implementation中,用@dynamic修饰之后,name属性将不会生成getter 和 setter方法。在下面这段代码中,用setter方法给name复制,系统会抛出“ -[ViewController setName:]: unrecognized selector sent to instance 0x7f95f2f07100”异常,这是由于系统找不到setName:这个方法。用runtime消息转发,有三次机会可以不让系统抛出这个异常(当然,把这个方法写上肯定是没问题的,但我们今天主题是:Runtime的转发机制)
我们在SomeOtherObject的 .m中实现setName:方法,让SomeOtherObject接受未处理的消息
#pragma mark - 1.重定向方法,在本类里进行方法重定向处理void dynamicMethodIMP(id self, SEL _cmd){ NSLog(@"dynamicMethodIMP -- %@", NSStringFromSelector(_cmd));}+ (BOOL)resolveInstanceMethod:(SEL)sel{ NSLog(@"sel is %@", NSStringFromSelector(sel)); // 当方法是setter方法时 if (sel == @selector(setName:)) { // 动态给本类添加方法 class_addMethod([SomeOtherObject class], sel, (IMP)dynamicMethodIMP, "v@:"); } return [super resolveInstanceMethod:sel];}#pragma mark - 2. 找个类处理她- (id)forwardingTargetForSelector:(SEL)aSelector{ if ([NSStringFromSelector(aSelector) isEqualToString:@"setName:"]) { return [[SomeOtherObject alloc] init]; } return [super forwardingTargetForSelector:aSelector];}#pragma mark - 3. 最后一步,把selector的所有细节包程NSInvocation, invocation对象负责分发消息给其他对象,这一步是完整的转发机制- (NSMethodSignature *)methodSignatureForSelector:(SEL)aSelector{ // (1)把2注释掉,1解开注释,依然有效// if ([NSStringFromSelector(aSelector) isEqualToString:@"setName:"]) {// return [NSMethodSignature signatureWithObjCTypes:"v@:"];// }// return [super methodSignatureForSelector:aSelector]; // (2) NSMethodSignature *signature = [super methodSignatureForSelector: aSelector]; if (signature == nil) { if ([SomeOtherObject instancesRespondToSelector:aSelector]) { signature = [SomeOtherObject instanceMethodSignatureForSelector:aSelector]; } } return signature; // 只有当返回值不是空的时候才能转发成功}// anInvocation里打包了此类不能处理的selector所有的细节- (void)forwardInvocation:(NSInvocation *)anInvocation{ // 将anInvocation里打包的消息,发送给SomeOtherObject处理,如果SomeOtherObject也不能处理,可以在它里面继续转发 // 这也是变相的实现了多继承,但是消息转发只是将一部分功能放到其他类,并没有多继承造成的代码过于丰富的问题 [anInvocation invokeWithTarget:[[SomeOtherObject alloc] init]];}
以上简单的介绍了一下Runtime的消息转发机制,这是我写的demo,感兴趣的小伙伴可以下载
点击这里查看demo
0 0
- Runtime消息转发机制
- Runtime消息转发机制
- runTime 的消息转发机制
- iOS runtime学习之消息转发机制
- ios runtime IMP指针 消息转发机制
- iOS Runtime与消息转发机制
- OC学习Runtime之消息传递,消息转发机制
- Runtime之消息转发
- iOS runtime 消息转发
- runtime基础、消息转发
- Objective-C runtime之消息转发机制(三)
- Objective-C runtime之消息转发机制(三)
- Objective-C runtime之消息转发机制(三)
- Objective-C runtime之消息转发机制(三)
- Objective-C runtime之消息转发机制(三)
- Objective-C runtime之消息转发机制(三)
- Objective-C runtime之消息转发机制(三)
- Objective-C Runtime guide 二(消息转发机制)
- 数据的多对一关系
- 【Nagios】【运维】Nagios 快速实现数据可视化的几种方式->统计图
- Android IPC机制-AIDL详解
- ARM指令格式
- 斯坦福自然语言组的NLP及计算语言学的资料汇总
- Runtime消息转发机制
- centos6.7 mini 安装 Galera Cluster
- QT编写多线程TCP文件接收服务器
- python写的crf训练代码
- win7快捷键汇总
- 推荐系统开源软件汇总和评点
- 【训练日记】20170324
- Ubuntu侧边栏添加Smartgit图标
- Kafka学习(一)——0.10.2.0版本基础知识,java简单的demo