美文网首页
iOS中load和initialize比较

iOS中load和initialize比较

作者: 秋风绿叶168 | 来源:发表于2020-01-15 00:56 被阅读0次

iOS开发中可以看到+load和+initialize两个方法, 网上对于这两个方法有很多的解释, 官方也有一定的说明, 但有些细节还是不够清楚, 今天我们来看看这两个方法.

load

Apple文档是这样描述的

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方法可能尚未被调用。

文档地址:developer.apple.com/reference/o…

load函数调用特点如下: 当类被引用进项目的时候就会执行load函数(在main函数开始执行之前),与这个类是否被用到无关,每个类的load函数只会自动调用一次.

1.父类的load方法执行顺序要优先于子类,如果父类调用过不会再调用 2.类中的load方法执行顺序要优先于类别(Category) 3.当有多个类别(Category)都实现了load方法,这几个load方法都会执行,其执行顺序跟编译顺序一致

initialize:

Apple文档是这样描述的

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

文档地址:developer.apple.com/reference/o…

initialize函数调用特点如下:

initialize在类或者其子类的第一个方法被调用前调用。即使类文件被引用进项目,但是没有使用,initialize不会被调用。

1.父类的initialize方法会比子类先执行 2.当子类未实现initialize方法时,会调用父类initialize方法,子类实现initialize方法时,会覆盖父类initialize方法. 3.当有多个Category都实现了initialize方法,会覆盖类中的方法,只执行一个,即会执行编译方法 列表中最后一个Category的initialize方法

什么情况下使用:

+load

由于调用load方法时的环境很不安全,我们应该尽量减少load方法的逻辑。另一个原因是load方法是线程安全的,它内部使用了锁,所以我们应该避免线程阻塞在load方法中

load很常见的一个使用场景,交换两个方法的实现

+initialize

initialize方法主要用来对一些不方便在编译期初始化的对象进行赋值。比如NSMutableArray这种类型的实例化依赖于runtime的消息发送,所以显然无法在编译器初始化:

总结:

load和initialize的共同点 1.如果父类和子类都被调用,父类的调用一定在子类之前

+load方法要点 当类被引用进项目的时候就会执行load函数(在main函数开始执行之前),与这个类是否被用到无关,每个类的load函数只会自动调用一次.

注意:

load调用时机比较早,当load调用时,其他类可能还没加载完成,运行环境不安全. load方法是线程安全的,它使用了锁,我们应该避免线程阻塞在load方法.

+initialize方法要点 initialize在类或者其子类的第一个方法被调用前调用。即使类文件被引用进项目,但是没有使用,initialize不会被调用。

在initialize方法收到调用时,运行环境基本健全。 initialize内部也使用了锁,所以是线程安全的。但同时要避免阻塞线程,不要再使用锁

相关文章

网友评论

      本文标题:iOS中load和initialize比较

      本文链接:https://www.haomeiwen.com/subject/lrurmctx.html