13类方法load和initialize的区别

http://www.cnblogs.com/ider/archive/2012/09/29/objective_c_load_vs_initialize.html

在objc语言里,有2个类初始化方法,+(void)load和+(void)initialize。
  • . +(void)initialize
    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.

  • . +(void)load
    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.
    All +load
    methods in your image.
    All C++ static initializers and C/C++ attribute(constructor)
    functions in your image.
    All initializers in frameworks that link to you.

In addition:
A class’s +load
method is called after all of its superclasses’ +load
methods.
A category +load
method is called after the class’s own +load
method.

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.

  Apple的文档很清楚地说明了initialize和load的区别在于:load是只要类所在文件被引用就会被调用,而initialize是在类或者其子类的第一个方法被调用前调用。所以如果类没有被引用进项目,就不会有load调用;但即使类文件被引用进来,但是没有使用,那么initialize也不会被调用。

它们的相同点在于:方法只会被调用一次。(其实这是相对runtime来说的,后边会做进一步解释)。
文档也明确阐述了方法调用的顺序:父类(Superclass)的方法优先于子类(Subclass)的方法,类中的方法优先于类别(Category)中的方法。
不过还有很多地方是文章中没有解释详细的。所以再来看一些示例代码来明确其中应该注意的细节。

    1. load,是加载类的时候,这里是Constants类,就会调用。也就是说,ios应用启动的时候,就会加载所有的类,就会调用这个方法。

      这样有个缺点,当加载类需要很昂贵的资源,或者比较耗时的时候,可能造成不良的用户体验,或者系统的抖动(dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{});用GCD可能会好点)。

    1. 这时候,就要考虑initialize方法了。这个方法可看作类加载的延时加载方法。类加载后并不执行该方法。只有当实例化该类的实例的时候,才会在第一个实例加载前执行该方法。比如:
      [Constants alloc];
      alloc将为Constants实例在堆上分配变量。这时调用一次initialize方法,而且仅调用一次,也就是说再次alloc操作的时候,不会再调用initialize方法了。
      initialize 会在运行时仅被触发一次,如果没有向类发送消息的话,这个方法将不会被调用。这个方法的调用是线程安全的。父类会比子类先收到此消息。

如果希望在类及其Categorgy中执行不同的初始化的话可以使用+load
+(void)load; 在Objective-C运行时载入类或者Category时被调用
这个方法对动态库和静态库中的类或(Category)都有效.

总结:

13类方法load和initialize的区别_第1张图片
方法对比.png

文/齐滇大圣(作者)
原文链接:http://www.jianshu.com/p/4530cf4b2292
著作权归作者所有,转载请联系作者获得授权,并标注“作者”。

你可能感兴趣的:(13类方法load和initialize的区别)