iOS开发之+load与+initialize

作者: 施忆 | 来源:发表于2018-02-13 19:58 被阅读407次

    一、+load

    +load方法是一定会在runtime中被调用的,只要类被添加到runtime中了,就会调用+load方法,即只要是在Compile Sources中出现的文件总是会被装载,与这个类是否被用到无关,因此+load方法总是在main函数之前调用。所以我们可以自己实现+laod方法来在这个时候执行一些行为。

    图1
    另外有意思的一点是,+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方法主要用来对一些不方便在编译期初始化的对象进行赋值,或者说对一些静态常量进行初始化操作。

    相关文章

      网友评论

        本文标题:iOS开发之+load与+initialize

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