美文网首页
load和initialize方法

load和initialize方法

作者: sun5kong | 来源:发表于2017-08-25 12:07 被阅读14次

    [图片上传中。。。(1)]###load

    load方法在这个文件被程序装载时调用. 只要在compile source中出现的文件总是会被装载, 这与这个类是否被调用到无关, 因此load 方法总是在main函数之前被调用.

    调用规则:

    如果一个类实现了load方法, 在调用这个方法前会调用父类的load方法. 而且这个过程是自动完成的, 并不需要我们手动实现:

    //In Parent.m
    + (void)load {
      NSLog(@"Load class Parent");
    }
    //In Child.m, 继承Parent
    + (void)load {
      NSLog(@"Load class Child");
    }
    // 运行结果:
    /*
        2016-02-01 21:28:14.379 load[11789:1435378] Load Class Parent
        2016-02-01 21:28:14.380 load[11789:1435378] Load Class Child
        2016-02-01 22:28:14.381 load[11789:1435378] Load Class Child+load
    */
    

    如果一个类没有实现load方法, 那么久不会调用它父类的load方法, 这一点与正常的类继承和方法调用都不一样, 需要额外注意.

    执行顺序

    load方法调用时,系统处于脆弱状态,如果调用别的类的方法,且该方法依赖于那个类的load方法进行初始化设置,那么必须确保那个类的load方法已经调用了,比如demo中的这段代码,打印出的字符串就为null:

    // In Child.m
    + (void)load {
        NSLog(@"Load Class Child");
    
        Other *other = [Other new];
        [other originalFunc];
    
        // 如果不先调用other的load,下面这行代码就无效,打印出null
        [Other printName];
    }
    

    load方法的调用顺序其实有迹可循,我们看到demo的项目设置如下:

    7F1B0C74BB20EB4DD7F68956D93E1D98.jpg

    在Compile Sources中,文件的排放顺序就是其装载顺序,自然也就是load方法调用的顺序。这一点也证明了load方法中会自动调用父类的方法,因为在demo的输出结果中,Parent的load方法先于Child调用,而它的装载顺序其实在Child之后。

    虽然在这种简单情况下我们可以辨别出各个类的load方法调用的顺序,但永远不要依赖这个顺序完成你的代码逻辑。一方面,这在后期的开发中极容易导致错误,另一方面,你实际上并不需要这么做

    使用场景

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

    + (void)load {
        Method originalFunc = class_getInstanceMethod([self class], @selector(originalFunc));
        Method swizzledFunc = class_getInstanceMethod([self class], @selector(swizzledFunc));
    
        method_exchangeImplementations(originalFunc, swizzledFunc);
    }
    

    相关文章

      网友评论

          本文标题:load和initialize方法

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