iOS基础知识基本知识研究基础知识

iOS load方法探究

2018-04-13  本文已影响61人  nullyy

iOS load方法探究

之前对某个类做Method Swilzzing都选择在该类的category中重写+ (void)load;方法, 相关方法交互的逻辑都写在该方法中.一直有一个疑惑,按照类的方法加载方式, 多个category都重写一个方法,那最终只会有一个方法会被真正调用到.那在category重写load方法是不是会无效?

我们实际写个demo,从以下几个问题分析下load方法,来解答我们的疑惑!

  1. load方法什么时候调用

    创建一个LoadObject对象, 在其m文件中重写load方法, 同时在main函数中打印log

#import "LoadObject.h"

@implementation LoadObject

+ (void)load{
    NSLog(@"%s",__func__);
}

@end

int main(int argc, char * argv[]) {
    @autoreleasepool {
        NSLog(@"%s",__func__);
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

输出:

2018-04-13 10:36:35.057750+0800 LoadMethodDemo[39024:1218412] +[LoadObject load]
2018-04-13 10:36:35.059119+0800 LoadMethodDemo[39024:1218412] main

结论: 类的load方法的调用发生在app main函数之前

  1. category中重写load方法

    为LoadObject类添加叫One的category

// LoadObject+One.m
@implementation LoadObject (One)

+ (void)load{
    NSLog(@"%s",__func__);
}

@end

输出:

2018-04-13 10:41:25.847033+0800 LoadMethodDemo[39127:1224463] +[LoadObject load]
2018-04-13 10:41:25.848094+0800 LoadMethodDemo[39127:1224463] +[LoadObject(One) load]
2018-04-13 10:41:25.848461+0800 LoadMethodDemo[39127:1224463] main

结论:
1. 类本身的load方法和category方法都被调用了
2. 类本身的load方法比category方法先调用

那我们试试多个category都重写load方法

再添加一个category,并重写load方法

// LoadObject+Two.m" 

@implementation LoadObject (Two)

+ (void)load{
    NSLog(@"%s",__func__);
}

@end

输出:

2018-04-13 10:44:56.270561+0800 LoadMethodDemo[39206:1228739] +[LoadObject load]
2018-04-13 10:44:56.274700+0800 LoadMethodDemo[39206:1228739] +[LoadObject(Two) load]
2018-04-13 10:44:56.275680+0800 LoadMethodDemo[39206:1228739] +[LoadObject(One) load]
2018-04-13 10:44:56.276437+0800 LoadMethodDemo[39206:1228739] main

结论: 所有分类中的load方法都会被调用

  1. 父类load方法

    创建LoadObject的子类SubLoadObject, 并且为其添加两个category, 分别重写load方法

//SubLoadObject.m

@implementation SubLoadObject

+ (void)load{
    NSLog(@"%s",__func__);
}

@end


#import "SubLoadObject+One.h"

@implementation SubLoadObject (One)

+ (void)load{
    NSLog(@"%s",__func__);
}

@end

#import "SubLoadObject+Two.h"

@implementation SubLoadObject (Two)

+ (void)load{
    NSLog(@"%s",__func__);
}

@end

输出:

2018-04-13 10:50:32.572034+0800 LoadMethodDemo[39336:1233577] +[LoadObject load]
2018-04-13 10:50:32.573519+0800 LoadMethodDemo[39336:1233577] +[SubLoadObject load]
2018-04-13 10:50:32.573761+0800 LoadMethodDemo[39336:1233577] +[SubLoadObject(One) load]
2018-04-13 10:50:32.574037+0800 LoadMethodDemo[39336:1233577] +[SubLoadObject(Two) load]
2018-04-13 10:50:32.574282+0800 LoadMethodDemo[39336:1233577] +[LoadObject(Two) load]
2018-04-13 10:50:32.574532+0800 LoadMethodDemo[39336:1233577] +[LoadObject(One) load]
2018-04-13 10:50:32.575050+0800 LoadMethodDemo[39336:1233577] main

结论:

  1. 父类的load方法先于子类调用
  2. 所有类本身的load方法先于category中的load方法调用
  3. category中的load方法调用顺序好像随机?

=========

总体结论:

  1. load方法调用发生在mian函数之前
  2. 类本身load方法和category中的load方法都会被调用
  3. 类本身load方法调用先于所有类的category类中的load方法调用

====

原理呢?
这个帖子原理讲得非常详细了

上一篇 下一篇

猜你喜欢

热点阅读