iOS开发

iOS Runtime运用之一 消息传递objc_msgSend

2020-04-08  本文已影响0人  神奇李白

关于runtime的运用有:
1 消息传递(调用方法): objc_msgSend
2 动态添加方法 : class_addMethod
3 交换方法(Method Swizzling)
4 动态添加属性(在分类中添加属性,以及获取私有属性或成员变量_ivar)
5 NSCoding自动归档解档
(场景:如果一个模型有许多个属性,实现自定义模型数据持久化时,需要对每一个属性都实现一遍encodeObject 和 decodeObjectForKey方法,比较麻烦。我们就可以使用Runtime获取属性列表遍历属性来解决。
原理:用runtime提供的函数遍历Model自身所有属性,并对属性进行encode和decode操作。)
6 字典转模型(原理同上)
7 热更新 比如jspatch 基础原理是OC的动态语言特性
OC的消息机制消息发送,动态解析,消息转发。就是在消息转发阶段动态的添加了方法的实现,以达到热修复的目的。
8 制作插件

objc_msgSend应用场景

  1. 创建并初始化对象
  2. 发送无参数无返回值的消息
  3. 发送有参数无返回值的消息
  4. 发送有参数有返回值",
  5. 带浮点返回值的消息"
//注意⚠️ 
#import <objc/runtime.h>
#import <objc/message.h>

创建并初始化对象

   //1.创建对象在执行Person *p = [[Person alloc]init]时,会转换成以下代码
   Person *person = ((Person * (*)(id, SEL))objc_msgSend)((id)[Person class], @selector(alloc));
   //2.初始化对象
   p = ((Person * (*)(id,SEL))objc_msgSend)((id)person, @selector(init));

发送无参数无返回值的消息

- (void)action_method1{
   ((void (*)(id,SEL))objc_msgSend)(self,@selector(action_test1));
}
- (void)action_test1{
    NSLog(@"执行了");
}

发送有参数无返回值的消息

- (void)action_method2{
    NSString *str = @"喵喵桑爱妙鲜包";
    ((void (*)(id, SEL, NSString *))objc_msgSend)(self, @selector(action_test2:),str);
}
- (void)action_test2:(id)info{
    NSLog(@"吃了小孩");
}

发送有参数有返回值的消息

- (void)action_method3{
    NSString *str = @"以前的字符串";
    str = ((id (*)(id, SEL, NSString *))objc_msgSend)(self, @selector(action_test3:),str);
    NSLog(@"str = %@",str);
}
- (id)action_test3:(id)info{
    return @"获得新的字符串";
}

发送带有浮点类型的消息 (可以用objc_msgSend_fpret)

- (void)action_method4{
    float price = ((float (*)(id, SEL))objc_msgSend_fpret)(self, @selector(action_test4));
    NSLog(@"价格price = %f",price);
}
- (float)action_test4{
    return 100.5;
}

发送带有结构体返回值的消息

- (void)action_method5{
    CGRect frame = ((CGRect (*)(id, SEL))objc_msgSend_stret)(self, @selector(action_test5));
    NSLog(@"frame = %@", NSStringFromCGRect(frame));
}
- (CGRect)action_test5{
    return CGRectMake(15, 0, 200, 100);
}
上一篇下一篇

猜你喜欢

热点阅读