一、+load
+load
方法是一定会在runtime中被调用的,只要类被添加到runtime中了,就会调用+load
方法,即只要是在Compile Sources
中出现的文件总是会被装载,与这个类是否被用到无关,因此+load
方法总是在main函数之前调用。所以我们可以自己实现+laod
方法来在这个时候执行一些行为。
另外有意思的一点是,
+load
方法不会覆盖。也就是说,如果子类实现了+load
方法,那么会先调用父类的+load
方法,然后又去执行子类的+load
方法。但要注意的时+load方法只会调用一次。而且执行顺序是:类 -> 子类 ->分类。而不同类之间的顺序不一定。
二、+initialize
+initialize
方法是在类或它的子类收到第一条消息之前被调用的,这里所指的消息包括实例方法和类方法的调用,并且只会调用一次。+initialize
方法实际上是一种惰性调用,也就是说如果一个类一直没被用到,那它的+initialize
方法也不会被调用,这一点有利于节约资源。
与+load
方法不同,却更符合我们预期的就是,+initialize
方法会覆盖。也就是说如果子类实现了+initialize
方法,就不会执行父类的了,直接执行子类本身的。如果分类实现了+initialize
方法,也不会再执行主类的。所以+initialize
方法的执行覆盖顺序是:分类 -> 子类 ->类。且只会有一个+initialize
方法被执行。
三、两者的异同
1、相同点
1).load和initialize会被自动调用,不能手动调用它们。
2).子类实现了load和initialize的话,会隐式调用父类的load和initialize方法。
3).load和initialize方法内部使用了锁,因此它们是线程安全的。
2、不同点
1).调用顺序不同,以main函数为分界,+load
方法在main函数之前执行,+initialize
在main函数之后执行。
2).子类中没有实现+load
方法的话,不会调用父类的+load
方法;而子类如果没有实现+initialize
方法的话,也会自动调用父类的+initialize
方法。
3).+load
方法是在类被装在进来的时候就会调用,+initialize
在第一次给某个类发送消息时调用(比如实例化一个对象),并且只会调用一次,是懒加载模式,如果这个类一直没有使用,就不回调用到+initialize
方法。
四、使用场景
1.+load
一般是用来交换方法Method Swizzle
,由于它是线程安全的,而且一定会调用且只会调用一次,通常在使用UrlRouter的时候注册类的时候也在+load
方法中注册。
2.+initialize
方法主要用来对一些不方便在编译期初始化的对象进行赋值,或者说对一些静态常量进行初始化操作。
网友评论