不得不知的 load 与 initialize

xiaoxiao2021-02-28  76

要想收获更多知识,还是得追其根源。OC 中有两个特殊的类方法,分别是 load 和 initialize, 本文主要总结一下这两个方面的区别与联系、使用场景和注意事项。

load

顾名思义,load 方法在这个文件被程序装载时调用,即当程序被载入内存时调用。只要是在 Compile Sources 中出现的文件总是会被装载,这与这个类是否被用到无关,因此 load 方法总是在 main 函数之前调用。

注意点:所谓 Compile Sources,详细见下图:

调用规则

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

父类 :

#import "Father.h" @implementation Father +(void)load { NSLog(@"Load Class Father"); } @end

子类:

#import "Children.h" @implementation Children +(void)load { NSLog(@"Load Class Children"); } @end

子类分类:

#import "Children+load.h" @implementation Children (load) +(void)load { NSLog(@"Load Class Child+load"); } @end

运行结果:

执行顺序

执行子类的 load 方法前,会先执行所有超类的 load 方法,顺序为:父类 -> 子类 -> 分类,这一点由上图也可以看出来。

load 方法调用时,系统处于脆弱状态,如果调用别的类的方法,且该方法依赖于那个类的 load 方法进行初始化设置,那么久必须确保那个类的 load 方法已经调用了。

使用场景

由于调用 load 方法时的环境很不安全,我们应该尽量减少 load 方法的逻辑。load 方法中最常用的就是方法交换,即 Method Swizzle。

initialize

在首次使用该类之前由运行期系统(非人为)调用,且仅调用一次;为惰性调用,也就是说如果一个类一直没被用到,那它的 initialize 方法也不会被调用,这一点有利于节约资源。

调用规则

与 load 方法类似的是,在 initialize 方法内部也会调用父类的方法,而且不需要我们显示的写出来。与 load 方法不同之处在于,即使子类没有实现 initialize 方法,也会调用父类的方法(原因:在创建子类对象时,首先要创建父类对象,所以会调用一次父类的 initialize 方法),这回导致很严重的问题。

正确使用 initialize 方法的姿势如下:

父类:

+ (void)initialize { if (self == [Father class]) { NSLog(@"Initialize Father, caller Class %@", [self class]); } }

加上判断后,就不会因为子类而调用到自己的 initialize 方法了。

使用场景

initialize 方法一般用于初始化全局变量或静态变量。例如设置整个 APP 的统一导航条及相关属性:

+ (void)initialize { if (self == [FGNavigationController class]) { // 获取当前类下面的导航条 UINavigationBar *navBar = [UINavigationBar appearanceWhenContainedIn:self, nil]; // 设置导航条背景图片 [navBar setBackgroundImage:[UIImage imageNamed:@"NavBar64"] forBarMetrics:UIBarMetricsDefault]; // 设置导航条文字标题 NSMutableDictionary *textAttr = [NSMutableDictionary dictionary]; // 颜色 textAttr[NSForegroundColorAttributeName] = [UIColor whiteColor]; textAttr[NSFontAttributeName] = [UIFont boldSystemFontOfSize:17]; // titleTextAttributes:给标题文字设置属性,(颜色,字体,阴影....) navBar.titleTextAttributes = textAttr; } }

总结

转载请注明原文地址: https://www.6miu.com/read-40894.html

最新回复(0)