iOS底层学习-day-5
前言-OC语法篇
我是一名iOS开发者, iOS底层 菜鸟的进阶之路30天。
问题
通过KVC修改属性会触发KVO么?
- 会触发KVO
Category的实现原理
- Category编译之后的底层结构是struct category_t,里面存储着分类的对象方法、类方法、属性、协议信息
- 在程序运行的时候,runtime会将Category的数据,合并到类信息中(类对象、元类对象中)
Category和Class Extension的区别是什么?
- Class Extension在编译的时候,它的数据就已经包含在类信息中
- Category是在运行时,才会将数据合并到类信息中
KVC的理解
- KVC的全称是Key-Value Coding,俗称“键值编码”,可以通过一个key来访问某个属性
- (void)setValue:(id)value forKeyPath:(NSString *)keyPath;
- (void)setValue:(id)value forKey:(NSString *)key;
- (id)valueForKeyPath:(NSString *)keyPath;
- (id)valueForKey:(NSString *)key
- 使用例子
[person setValue:[NSNumber numberWithInt:10] forKey:@"age”];//因为里面是id所以要用[NSNumber numberWithInt:10]
[person setValue:@10 forKey:@"age"];
person.cat = [[MJCat alloc] init];
[person setValue:@10 forKeyPath:@"cat.weight"];
- forKey和forKeyPath的区别
//forKeyPath可以嵌套多层查找,找到的可以是子类的属性
person.cat = [[MJCat alloc] init];
[person setValue:@10 forKeyPath:@"cat.weight"];
通过KVC修改属性会触发KVO?
- 因为setValue会寻找 setKey: _setKey:
- setValue 原理图
- valueForKey 原理图
- KVC直接修改成员的属性会比手动调用KVO直接修改成员属性,还是会触发KVO监听,因为KVC内部有自己手动调用wiillchange和didchange方法
Category的理解
- category的方法的存放 :一个类只有一个类对象
- 分类的对象方法 是放在类对象的方法列表中
- 分类的类方法 是放在元类对象的类方法列表中
- category为什么没有合并到对象的类方法中
- 这些分类的类方法和对象方法是在程序运行时通过runtime生成的
其实就是生成分类的结构体对象
struct _category_t {
const char *name;//类名
struct _class_t *cls;//类的信息
const struct _method_list_t *instance_methods;//方法列表
const struct _method_list_t *class_methods;//对象类方法
const struct _protocol_list_t *protocols;//协议
const struct _prop_list_t *properties;//属性
};
- 所以是没有合并到类中的
如果生成很多的分类那么就是结构体不变,结构体的数据改变而已 - 如果在分类中和类中的方法相同,那么就是直接找到类对象的方法了,而不是直接覆盖方法
- category中的方法运行顺序
- 通过Runtime加载某个类的所有Category数据
- 把所有Category的方法、属性、协议数据,合并到一个大数组中,后面参与编译的Category数据,会在数组的前面
- 将合并后的分类数据(方法、属性、协议),插入到类原来数据的前面
源码解读顺序
- 源码解读顺序
objc-os.mm
_objc_init
map_images
map_images_nolock
objc-runtime-new.mm
_read_images
remethodizeClass
attachCategories
attachLists
realloc、memmove、 memcpy