杂乱

Load 和 initialize 方法

2017-01-20  本文已影响149人  蜗牛也有梦想

load:
当类被引用进程序的时候会执行这个函数。
在一个程序开始运行之前(在main函数开始执行之前),在库开始被程序加载,load函数就会开始被执行。
我们开发的程序都可以认为是一个库,但是库又不会独立存在(我们的程序还会引用其他库,也可能被其他函数引用),所以库的初始化顺序可以如下:

1初始化我们引用的库
2执行我们自己库的Objective-C的load函数
3执行C++和C的static初始化变量
4初始化引用我们库的其他库

当父类和子类都实现load函数时,父类的load函数会被先执行。load函数是系统自动加载的,因此不需要调用父类的load函数,否则父类的load函数会多次执行。
在Category中写load函数是不会替换原始类中的load函数的,原始类和Category中的load函数都会被执行,原始类的load会先被执行,再执行Category中的load函数。当有多个Category都实现了load函数,这几个load函数执行顺序不确定。

initialize:
当类第一次被执行到的时候这个函数会被执行。
如果类包含继承关系,父类的initialize函数会比子类先执行。由于是系统自动调用,也不需要显式的调用父类的initialize,否则父类的initialize会被多次执行。
假如这个类放到代码中,而这段代码并没有被执行,这个函数是不会被执行的。

总结:
1.将针对于类修改放在intialize中,将针对Category的修改放在load中。
2.但是假如我们是修改系统的类,一般会通过添加Category来添加功能,但是如果修改initialize会导致原生的intialize不会执行,所以放在load中会比较妥当。
3.在加载阶段,如果类实现了load方法,那么系统就会调用它,分类里也可以调用此方法,类的load方法要比分类的load方法先执行。与其他方法不同,load方法不参与覆写机制;
4.首次使用某个类之前,系统会向其发送initialize消息。由于此方法遵循普通的覆写规则,所以通常应该在里面判断当前要初始化的是哪个类;
5.load与initialize都应该实现得精简,有助于保持程序的响应能力;
6.无法在编译期设定的全局变量,可以放在initialize方法中初始化。

iOS的load方法与initialize方法
load
Invoked whenever a class or category is added to the Objective-C runtime; implement this method to perform class-specific behavior upon loading.

当类(Class)或者类别(Category)加入Runtime中时(就是被引用的时候)。
实现该方法,可以在加载时做一些类特有的操作。

Discussion
The load message is sent to classes and categories that are both dynamically loaded and statically linked, but only if the newly loaded class or category implements a method that can respond.

The order of initialization is as follows:

All initializers in any framework you link to.
调用所有的Framework中的初始化方法

All +load methods in your image.
调用所有的+load方法

All C++ static initializers and C/C++ attribute(constructor) functions in your image.
调用C++的静态初始化方及C/C++中的attribute(constructor)函数

All initializers in frameworks that link to you.
调用所有链接到目标文件的framework中的初始化方法

In addition:

A class’s +load method is called after all of its superclasses’ +load methods.
一个类的+load方法在其父类的+load方法后调用

A category +load method is called after the class’s own +load method.
一个Category的+load方法在被其扩展的类的自有+load方法后调用

In a custom implementation of load you can therefore safely message other unrelated classes from the same image, but any load methods implemented by those classes may not have run yet.
在+load方法中,可以安全地向同一二进制包中的其它无关的类发送消息,但接收消息的类中的+load方法可能尚未被调用。

initialize
Initializes the class before it receives its first message.

在这个类接收第一条消息之前调用。

Discussion
The runtime sends initialize to each class in a program exactly one time just before the class, or any class that inherits from it, is sent its first message from within the program. (Thus the method may never be invoked if the class is not used.) The runtime sends the initialize message to classes in a thread-safe manner. Superclasses receive this message before their subclasses.

Runtime在一个程序中每一个类的一个程序中发送一个初始化一次,或是从它继承的任何类中,都是在程序中发送第一条消息。(因此,当该类不使用时,该方法可能永远不会被调用。)运行时发送一个线程安全的方式初始化消息。父类的调用一定在子类之前。

对比 +(void)load +(void)initialize
执行时机 程序运行后,main函数之前 类第一次使用的时候
执行次数 1 1
是否沿用父类

对比
相同点
在不考虑开发者主动使用的情况下,系统最多会调用一次
如果父类和子类都被调用,父类的调用一定在子类之前,
类中的方法优先于类别(Category)中的方法。
都是为了应用运行提前创建合适的运行环境
在使用时都不要过重地依赖于这两个方法,除非真正必要
不同点
load是只要类所在文件被引用就会被调用(这里是引用进项目,不是被其他的文件引用),而initialize是在类或者其子类的第一个方法被调用前调用。所以如果类没有被引用进项目,就不会有load调用;但即使类文件被引用进来,但是没有使用,那么initialize也不会被调用。

对比 +(void)load +(void)initialize
执行时机 程序运行后,main函数之前 类第一次使用的时候
执行次数 1 1
是否沿用父类
对比 +(void)load +(void)initialize
执行时机 right-aligned $1600
执行次数 1 1
是否沿用父类

参考资料:
iOS类重要的两个方法 load 和 initialize
http://blog.csdn.net/hncsy403/article/details/53768540
apple官网 load和initialize说明
https://developer.apple.com/reference/objectivec/nsobject/1418639-initialize?language=objc
iOS的load方法与initialize方法
http://www.jianshu.com/p/65da302fc62c
细说OC中的load和initialize方法
http://www.jianshu.com/p/d25f691f0b07
OC中类的load和initialize方法
http://blog.csdn.net/u014084081/article/details/48265453
Objective C类方法load和initialize的区别
http://www.cnblogs.com/ider/archive/2012/09/29/objective_c_load_vs_initialize.html
NSObject的load和initialize方法 (大神制作)
http://www.molotang.com/articles/1929.html
Objective-C 中 +load 与 +initialize
http://justsee.iteye.com/blog/1630979

上一篇 下一篇

猜你喜欢

热点阅读