initialize、load

无意中看到这方面的内容,查了查,记录下~
load
OC也是运行时语言,在运行之前肯定要加在程序里的一些类文件,而这个load方法就是在加载类的时候调用的,可以在里面做一些自己的处理。从NSObject类里看到这个方法表面上看起来跟其他的类方法没有什么差别,但是其实是有差别的。其实可以尝试下写个类重写下这个方法,会发现他的调用在main之前 ,而且无关你有没有使用这个类。并且如果父类子类及类别都重写此方法,会发现调用的顺序是父类-》子类-》类别。
initialize、load
文章图片
load 方法 会在程序加载类文件的时候就会调用 无关乎这个类是否用到,所有程序里存在的类都会调用load方法,一般不在这个方法里做太多的事情。

如果子类父类及类别都复写了这个方法,会优先调用父类,然后子类 ,最后再是类别。
load方法调用时,系统处于脆弱状态,如果调用别的类的方法,且该方法依赖于那个类的load方法进行初始化设置,那么必须确保那个类的load方法已经调用了,如果别的类还没有装载调用load方法,就可能产生意想不到的异常,其实load方法的顺序跟程序工程文件 里 complie source的加载顺序有关。load方法的环境不稳定,但是线程安全。常见使用场景 也就是在load 里做 Method Swizzle,例如
+ (void)load {
Method originalFunc = class_getInstanceMethod([self class], @selector(originalFunc));
Method swizzledFunc = class_getInstanceMethod([self class], @selector(swizzledFunc));
method_exchangeImplementations(originalFunc, swizzledFunc);
}
一般来说,除了Method Swizzle,别的逻辑都不应该放在load方法中实现。
而initialize方法不同,会在你第一次使用的时候会调用,调用的时候 运行环境基本已经健全了

这个方法在第一次给某个类发送消息时调用(比如实例化一个对象),并且只会调用一次。initialize方法实际上是一种惰性调用,也就是说如果一个类一直没被用到,那它的initialize方法也不会被调用,这一点有利于节约资源
与load方法不同之处在于,即使子类没有实现initialize方法,也会调用父类的方法,这会导致一个很严重的问题:[Man alloc]init] 之后调用俩次person的initialize 方法而子类Man并没有实现initialize方法
虽然initialize方法对一个类而言只会调用一次,但这里由于出现了两个类,所以调用两次符合规则,但不符合我们的需求。正确使用initialize方法的姿势如下
+ (void)initialize {
if (self == [Parent class]) {
NSLog(@"Initialize Parent, caller Class %@", [self class]);
}
}
【initialize、load】一般做一些全局变量和静态变量的初始化


initialize、load
文章图片

    推荐阅读