iOS之学习总结

一、load 方法

1、load方法加载

  • +Load方法会在runtime加载类、分类时调用
  • 每个类、分类的+load方法,在程序运行过程中只调用一次。

2、调用顺序

  1. 先调用类的+load方法

    • 按照编译先后顺序调用(先编译,先调用)
    • 调用子类的+load方法之前会先调用父类的+load方法
  2. 再调用分类的+load方法

    • 按照编译先后顺序调用(先编译先调用)

3、load加载过程底层原发源码执行顺序

  1. _objc_init: 加载对象的入口方法,_objc_init里面调用load_images方法

  2. load_images :加载所有类load的方法,里面调用prepare_load_methods、call_load_methods.

  3. prepare_load_methods:加载load方法的准备工作

    1. classref_t *classList = _getObjc2NonlazyClassList(mhdr, &count)方法获取所有类,遍历classList
      • 遍历classList,调用schedule_class_load(class cls):
        • 先 递归调用schedule_class_load(cls->superclass)调用父类
        • add_class_to_loadable_list:讲cls加载到数据的后面
    2. category **categoryList = _getObjc2NonlazyCategoryList(mhdr, &count);获取所有分类。
      • 遍历categoryList,调用add_category_to_loadable_list把分类加到列表最后面。

(categoryList是一个二维数组里,第一维代表是某一个类,第二维代表的是某个类下面有多个分类。
[person_category_list,stu_categorylist].
person_category_list = [category_t, category_t]
stu_category_list = [category_t, category_t]

  1. call_load_methods:调用load方法列表
    • call_class_loads():先加载完类的load方法

      • 类的加载过程,遍历add_class_to_loadable_list中类,调用load_method函数调用load方法。
    • call_category_loads():在加载分类的load方法

      • 分类的加载过程,遍历add_class_to_loadable_list中类,调用load_method函数调用load方法。

类和分类最后都会调用(*load_method)(cls, SEL_load) 这个函数,+load方法是根据方法地址直接调用,并不是经过objc_msgSend函数调用。

二、initialize方法

一、initialize调用时机

  • +initialize 方法会在类第一次收到消息时调用

    • 先调用父类的+initlialize,在调用子类的+initialize。

二、底层源码实现

  1. 调用objc_msgSend
    • class_getClassMethod(Class cls,SEL sel)(找类方法,传的就是元类)

    • lookUpImpOrNil 找方法

    • lookUpImpOrForward 继续查找

    • if (initialize && !cls->isInitialize) {
      _class_initialize方法调用initialize
      } 先判断是否需要初始化,需要的话就调用

    • callInitialize调用initialize

    • 最后调用到 objc_msgSend(cls, SEL_initialize)

三.load 与initialize区别

1、调用方式

  • load是根据函数地址调用
  • initialize是通过objc_msgSend调用

2、调用时刻

  • load是runtime加载类、分类的时候调用(只会调用一次)
  • initialize是类第一次接收到消息的时候调用,每一个类只会initialize一次(父类的initialize方法可能会被调用多次,当多个子类没有自己实现initialize,会调用父类)

3、l调用顺序

load调用顺序:
  • 先调用类的load

    • 先编译的类,优先调用load
    • 调用子类的load之前,会先调用父类的load
  • 在调用分类的load

    • 先编译的分类,优先调用load
initialize调用顺序
  • 先初始化父类
  • 再初始化子类(子类没实现,最终调用的是父类的initialize方法)

三、关联对象

给分类添加属性,分类只声明没有方法的实现,实现的方式是关联对象。
关联对象所用的相关类主要是下面4个类:

  • AssociationManager
  • AssociationHashMap
  • ObjectAssociationMap
  • ObjcAssociation

使用方式

分类.h文件
@property(nonatomic,copy)NSString *name;

分类.m文件

- (void)setName {
    objc_setAssociatedObject( self,
                                @slector(name), OBJC_ASSOCIATION_COPY_NONATOMIC)
}

- (void)name {
    objc_getAssociatedObject( self,
                                @slector(name), OBJC_ASSOCIATION_COPY_NONATOMIC)
}

第一个参数给关联对象

第二个是key

第三参数是关联策略

  • objc_AssociationPolicy :对应的修饰符

    • OBJC_ASSOCIATION_ASSIGN :assign
    • OBJC_ASSOCIATION_RETAIN_NONATOMIC: strong, nonatomic
    • OBJC_ASSOCIATION_COPY_NONATOMIC: copy, nonatomic
    • OBJC_ASSOCIATION_RETAIN:strong, atomic
    • OBJC_ASSOCIATION_COPY :copy, atomic

关联对象的核心原理

  • AssociationManager中声明一个全局的haspmap。
class AssociationManager {
    static AssociationHashMap *_map;
}
  • AssociationHashMap中存储着键值对,key是这个关联的object,值是Object AssociationMap这个也是对象的hasmap
 AssociationHashMap : public unordered_map<disguised_prt_t, Object  AssociationMap>

如下面表格:

key value
disguised_prt_t Object AssociationMap
disguised_prt_t Object AssociationMap
  • AssociationMap这个也是一个存储着键值对的hashmap
class ObjectAssociationMap : public std ::map <void *, ObjcAssociation>

如下面的表格:

key value
void * ObjcAssociation
void * ObjcAssociation
  • ObjcAssociation 包含关联策略和值,如下:
class ObjcAssociation {
    uintptr_t _policy;
    id _value;
}

关联对象的原理执行流程如下图:

[图片上传失败...(image-212701-1620575201542)]

3、移除关联对象

  • 设置关联对象为nil,就相当于移除关联对象
  • remove_Association(self) 移除该对象所有的挂链对象

4.关联对象总结

  • 关联对象并不是存储在关联对象本身内存中
  • 关联对象存储在全局同意的一个AssociationsManager中

四、KVO

1、kvo 使用

  • 注册观察者
/*
@observer:就是观察者,是谁想要观测对象的值的改变。
@keyPath:就是想要观察的对象属性。
@options:options一般选择NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld,
这样当属性值发生改变时我们可以同时获得旧值和新值,如果我们只填NSKeyValueObservingOptionNew则属性发生改变时只会获得新值。
@context:想要携带的其他信息,比如一个字符串或者字典什么的。
*/
- (void)addObserver:(NSObject *)observer forKeyPath:(NSString *)keyPath 
options:(NSKeyValueObservingOptions)options context:(nullable void *)context;
  • 监听回调
/*
@keyPath:观察的属性
@object:观察的是哪个对象的属性
@change:这是一个字典类型的值,通过键值对显示新的属性值和旧的属性值
@context:上面添加观察者时携带的信息
*/
- (void)observeValueForKeyPath:(nullable NSString *)keyPath 
ofObject:(nullable id)object change:(nullable NSDictionary<NSKeyValueChangeKey, id> *)change 
context:(nullable void *)context;
  • kvo 原理

如下图:

KVO执行过程.png

五、KVC实现原理

  • setValue: forKey

执行流程如下图:


KVC赋值.png
  • valueForKey

执行流程如下图:

KVC取值.png

六、关联对象结构图

关联对象.png

七、Notification通知心原理

Notification通知心原理

八、响应链和事件传递

响应链和事件传递

九、编程中的六大设计原则

编程中的六大设计原则

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 160,165评论 4 364
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,720评论 1 298
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 109,849评论 0 244
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 44,245评论 0 213
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,596评论 3 288
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,747评论 1 222
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,977评论 2 315
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,708评论 0 204
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,448评论 1 246
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,657评论 2 249
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,141评论 1 261
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,493评论 3 258
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,153评论 3 238
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,108评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,890评论 0 198
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,799评论 2 277
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,685评论 2 272

推荐阅读更多精彩内容