OC中load和initialize方法

前言

最近在因为工作的原因,空余时间相对多了一点。所以准备好好整理一下OC相关的基础知识,以便加固相关的知识点。

+load方法

调用时机

  1. +load方法会在runtime加载类和分类时调用;
  2. 每个类和分类在程序运行中只调用一次+load方法;
  3. 只要是在Compile Sources中的文件总会被加载,这与这个类是否被用到无关,因此+load方法总是在main函数之前被调用。

调用顺序

  1. 执行父类的+load方法
  2. 执行当前类的+load方法
  3. 执行分类的+load方法
  4. 不同的类之间方法调用顺序根据Compile Sources中文件的顺序来
    下面我们看下实际调用情况:
//Person.m
+ (void)load {
    NSLog(@"====== Person load function ======");
}

//Fruit.m
+ (void)load {
    NSLog(@"====== Fruit load function ======");
}

//Person子类Student
+(void)load {
    NSLog(@"======= Student load function =======");
}

//Person子类 Boy
+(void)load {
    NSLog(@"===== Boy load function =====");
}

//Person+Height分类
+(void)load {
    NSLog(@"===== Person (Height) load function =====");
}

//Person+Gender分类
+ (void)load {
    NSLog(@"======= Person (Gender) load function ========");
}
//运行结果
/*
2019-07-24 17:36:54.231549+0800 LoadDemo[10707:328172] ====== Person load function ======
2019-07-24 17:36:54.232529+0800 LoadDemo[10707:328172] ======= Student load function =======
2019-07-24 17:36:54.232701+0800 LoadDemo[10707:328172] ===== Boy load function =====
2019-07-24 17:36:54.232834+0800 LoadDemo[10707:328172] ====== Fruit load function ======
2019-07-24 17:36:54.232949+0800 LoadDemo[10707:328172] ===== Person (Height) load function =====
2019-07-24 17:36:54.233059+0800 LoadDemo[10707:328172] ======= Person (Gender) load function ========
2019-07-24 17:36:54.233225+0800 LoadDemo[10707:328172] ============== main function =========/n
*/

如果一个类没有实现+load方法,那么就不会调用它的+load方法。在Compile Sources中,文件的排放顺讯就是其加载顺序,也就是+load方法的调用顺序。从其中也可以看出Person+load方法调用顺序优先于子类BoyStudent的顺序。同时子类中+load方法的调用顺序则是Compile Sources中文件的摆放顺序。

使用场景
从上面可以看出+load函数调用在main函数之前,同时+load方法时的环境很不安全,我们应该尽量减少+load方法的逻辑。另一个原因是+load的方法是线程安全的,它内部使用了锁,所以我们应当避免线程阻塞在+load方法中。
常见的使用+load方法的场景就是Method Swizzle:

+ (void)load {
    Method orginalFunc = class_getInstanceMethod([self class], @selector(originalFunc));
    Method swizzleFunc = class_getInstanceMethod([self class], @selector(swizzleFunc));
    method_exchangeImplementations(orginalFunc, swizzleFunc);
}

initialize调用

调用时机

initialize方法在第一次给某个类发送消息时调用(比如实例化一个对象),并且只会调用一次。该方法实际上是一种惰性方法,也就是说如果一个类没有被用到,那它的initialize方法就不会调用。

调用顺序
  1. 先调用父类的initialize方法,并且即使子类没有实现initialize方法,也会调用父类方法。
  2. 创建子类,如果子类没有实现initialize方法,父类initialize方法会调用多次。因为创建子类对象是要创建父类对象
  3. 有分类的类会调用分类实现的initialize方法,而不调用当前类的initialize方法。
//Person.m
+ (void)initialize {
    NSLog(@"===== Person initialize function =====");
}
//调用
 Student *student = [[Student alloc] init];

// Student中未实现initialize方法,打印结果
2019-07-25 15:20:51.585788+0800 LoadDemo[19894:580248] ===== Person initialize function =====
2019-07-25 15:20:51.585972+0800 LoadDemo[19894:580248] ===== Person initialize function =====

//Student中实现initialize方法,打印结果
2019-07-25 15:23:06.068990+0800 LoadDemo[19929:581522] ===== Person initialize function =====
2019-07-25 15:23:06.069200+0800 LoadDemo[19929:581522] ===== Student initialize function =====

要避免分类为实现initialize方法,导致父类initialize方法多次调用可以使用如下方式:

+ (void)initialize {
    if (self == [Person class]) {
        NSLog(@"===== Person initialize function =====");
    }
}
使用场景

在initialize中可以初始化一些静态对象

static NSMutableArray *emptyArray;

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

推荐阅读更多精彩内容