编写高质量iOS与OS X代码的52个有效方法--第51条
第51条:精简load与initialize的实现代码
1.这两个方法是干什么的
很多时候一个类在使用之前必须执行某些初始化方法,然后才能正常使用。NSObject这个类有两个方法load和initialize用来执行初始化方法。
2.load方法的特点
加入runtime的所有类和分类都必须执行这个方法,而且在程序执行过程中只会执行一次。不会像其他方法一样只执行分类中的方法而不执行原有类的方法。(分类中的方法并不是真的覆盖了原有类的方法,而是放在了方法列表里靠前的位置,导致调用的时候先调用了分类里的方法)
为iOS系统设计的程序在启动的时候,会执行所有类和分类的load方法,但是无法确定各个类的载入顺序,也就是无法确定load方法的执行顺序。
⚠️:不可以在load方法里使用其他的类。
+(void)load{
EClassA *object = [EClassA new];
}
❓:如果我们在B类的load方法里调用A类,那这个时候就可能会产生问题,A类的load方法可能还没有执行,因为各个类的加载顺序不确定,也就是说A类的初始化还没有做完,就使用了它,是不安全的。
load方法和其他方法不同,不支持继承体系,如果某个类的load方法没有实现,无论此类的各级超类有没有实现load方法都不会去调用。
❓:为什么不会去执行父类的load方法呢,因为load方法和其他oc中的方法实现的本质是不一样的,他没有一个消息发送的过程,所以就不会到父类的方法列表中去查找。
⚠️:程序在执行load方法的时候整个会阻塞,所以如果load方法很复杂那么整个程序都会卡住。
3.initialize方法的特点
这个方法也用来执行和类初始化相关的操作。
这个方法是惰性调用的,就是说程序在运行时只有用到了这个类才会调用这个类的initialize方法。
在initialize方法中可以安全的调用任意类的任意方法,不会出现不安全的情况。
如果某个类没有实现initialize方法,但是超类实现了,就会去调用超类的initialize方法。因为initialize方法实现的本质其实是消息转发,所以就会去父类的方法列表里查找。
分类中的initialize方法会覆盖原有类中的initialize方法,因为他被加到了方法列表更靠前的位置。
如果一个类有多个子类,那么他的initialize方法可能会被调用多次,因此在实现时候可以判断一下是不是子类调用的。