iOS复习之RunTime

1. 对象、类对象、元类对象
2. 消息传递机制
3. 消息转发流程
4. Method Swizzling (交换方法)
5. class_addMethod (动态添加方法)
6. objc_getAssociatedObject objc_setAssociatedObject


RunTime 

主要 RunTime文章:

Objective-C特性:Runtime
让你快速上手Runtime
iOS 程序员 6 级考试(答案和解释)

Swift RunTime 视频:
Swift RunTime

      OC是一门弱类型语言、动态语言,区别于C语言等面向过程编程(编译时就确定了调用哪个函数),区别于Swift强类型语言编译时有语法错误会实时提示,OC一些隐藏的BUG不会提示(如URL为空等情况)。OC编译时并不确定调用哪个函数,运行时才确定调用哪个函数,即SEL(函数编号)编译时不确定调用哪个IMP(函数指针),SEL -> IMP(映射关系)。
      我们一般用OC动态特性使用一些RunTime黑魔法,如交换方法,动态添加属性,动态添加方法,RunTime底层使用C进行一层封装,OC方法再对RunTime进行一层封装。

1、消息传递机制

导入头文件 #import ,Build Settings 中 Enable Strict Checking of objc_msgSend Calls 至为NO。

创建类Person,实现eat方法,调用eat方法的几种方式:
1> Person *person = [[Person alloc] init]; [person eat];
2> [person performSelector:@selector(eat)];
3> objc_msgSend(person,@selector(eat));

堆栈区别:
堆:程序员自己alloc手动创建的。
栈:系统分配的。


导入头文件  #import  

2、交换方法

获取SEL函数编号:
sel_registerName("") -> SEL
NSSelectorFromString(@"") -> SEL

获取类:
NSClassFromString(@"") -> Class
objc_getClass("") -> Class

//  APP在手机的硬盘里,当加载类到内存的时候调用load方法
+ (void)load;

获取类方法:
class_getClassMethod(self, @selector(imageWithName:)) -> Method

获取类对象方法(实例方法)
class_getInstanceMethod(Class,SEL)

// 交换两个方法的实现,一般用于给系统自带方法添加额外的方法
method_exchangeImplementations(Method_Nonnull m1, Method_Nonnull m2)

3、动态添加方法

1) Q:子类继承父类的方法,子类里面有父类的方法吗?
A:没有,系统查找子类中没有该方法时,会往上查找子类的父类。只有子类override(重载、重写)时才有这个方法,调用super继承父类的属性行为。

// 当这个类调用了一个没有实现的类方法,可动态添加方法
+(BOOL)resolveClassMethod:(SEL)sel;

// 当这个类调用了一个没有实现的实例方法,可动态添加方法
+(BOOL)resolveInstanceMethod:(SEL)sel;

// 动态添加eat方法
// 第一个参数:给哪个类添加方法
// 第二个参数:添加方法的方法编号
// 第三个参数:添加方法的函数实现(函数地址)
// 第四个参数:函数的类型,(返回值+参数类型) v:void @:对象->self :表示SEL->_cmd

class_addMethod(self, @selector(eat), eat, "v@:");

4.给分类添加属性

NSObject *objc = [[NSObject alloc] init];
objc.name = @"小码哥"; // Set
NSLog(@"%@",objc.name); // Get

// 定义关联的key
static const char *key = "name";

- (NSString *)name
{
     // 根据关联的key,获取关联的值。
     return objc_getAssociatedObject(self, key);
}

- (void)setName:(NSString *)name
{
     // 第一个参数:给哪个对象添加关联
     // 第二个参数:关联的key,通过这个key获取
     // 第三个参数:关联的value
     // 第四个参数:关联的策略

     objc_setAssociatedObject(self, key, name, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

你可能感兴趣的:(iOS复习之RunTime)