可能有些还不清楚load和initialize的区别,下面简单说一下:

首先说一下 + initialize 方法:苹果官方对这个方法有这样的一段描述:这个方法会在 第一次初始化这个类之前 被调用,我们用它来初始化静态变量.

initialize方法的调用时机,当向该类发送第一个消息(一般是类消息首先调用,常见的是alloc)的时候,先调用类中的,再调用类别中的(类别中如果有重写);如果该类只是引用,没有调用,则不会执行initialize方法。
两者方法的共同点:自动调用父类的,不需要super操作;自动调用仅仅会调用一次(不包括外部显示调用).

load 方法会在加载类的时候就被调用,也就是 ios 应用启动的时候,就会加载所有的类,就会调用每个类的 + load 方法.

load方法的调用时机,main函数之前,先调用类中的,再调用类别中的(类别中如果有重写).

代码演示:

#pragram ---main函数中的代码---
#import <UIKit/UIKit.h>
#import "AppDelegate.h"
int main(int argc, char * argv[]) {
NSLog(@"%s",__func__);
@autoreleasepool {
return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
} #pragram ---基于NSObject的Person类---
#import "Person.h"
@implementation Person
+ (void)load{
NSLog(@"%s",__func__);
}
+ (void)initialize{
[super initialize];
NSLog(@"%s %@",__func__,[self class]);
}
- (instancetype)init{
if (self = [super init]) {
NSLog(@"%s",__func__);
}
return self;
}
@end #pragram ---基于Person的Son类---
#import "Girl.h"
@implementation Girl
+ (void)load{
NSLog(@"%s ",__func__);
}
+ (void)initialize{
[super initialize];
NSLog(@"%s ",__func__);
}
- (instancetype)init{
if (self = [super init]) {
NSLog(@"%s",__func__);
}
return self;
}
@end

输出日志:

-- ::36.535 initialize[:]] +[Person load]
-- ::36.535 initialize[:]] +[Girl load]
-- ::36.535 initialize[:]] main

这说明在我并没有对类做任何操作的情况下,+load 方法会被默认执行,并且是在 main 函数之前执行的。

#接下来我们来查看一下 + initialize 方法,先在 ViewController 中创建 Person 和 Girl 对象:

#import "ViewController.h"
#import "Person.h"
#import "Son.h"
#import "Girl.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
Person * p1 = [Person new];
Person * p2 = [Person new];
Girl *c1 = [Girl new];
Girl *c2 = [Girl new];
}
@end

输出日志:

-- ::57.134 initialize[:] +[Person load]
-- ::57.135 initialize[:] +[Girl load]
-- ::57.136 initialize[:] main
-- ::57.198 initialize[:] +[Person initialize] Person
-- ::57.198 initialize[:] -[Person init]
-- ::57.198 initialize[:] -[Person init]
-- ::57.198 initialize[:] +[Girl initialize]
-- ::57.199 initialize[:] -[Girl init]
-- ::57.199 initialize[:] -[Girl init]

+ initialize 方法类似一个懒加载,如果没有使用这个类,那么系统默认不会去调用这个方法,且默认只加载一次;

+ initialize 的调用发生在 +init 方法之前.

那么+ initialize 在父类与子类之间的关系是什么杨,我们创建一个继承自 Person 类的 Son类:

#pragram ---ViewController 中的代码---
#import "ViewController.h"
#import "Person.h"
#import "Son.h"
#import "Girl.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
Person * p1 = [Person new];
Person * p2 = [Person new];
Son*s = [Son new];
}
@end

输出日志:

-- ::14.140 initialize[:] +[Person load]
-- ::14.142 initialize[:] +[Son load]
-- ::14.142 initialize[:] +[Girl load]
-- ::14.142 initialize[:] main
-- ::14.203 initialize[:] +[Person initialize] Person
-- ::14.203 initialize[:] -[Person init]
-- ::14.203 initialize[:]] -[Person init]
-- ::14.204 initialize[:] +[Person initialize] Son
-- ::14.204 initialize[:] -[Person init]

我们会发现 Person 类的 + initialize 方法又被调用了,但是查看一下是子类 Son 调用的,也就是创建子类的时候,子类会去调用父类的 + initialize 方法。

这是因为在创建子类对象时,首先要创建父类对象,所以会调用一次父类的initialize方法,然后创建子类时,尽管自己没有实现initialize方法,但还是会调用到父类的方法。

虽然initialize方法对一个类而言只会调用一次,但这里由于出现了两个类,所以调用两次符合规则,但不符合我们的需求。正确使用initialize方法的姿势如下

// In Person.m
+ (void)initialize {
if (self == [Person class]) {
NSLog(@"Initialize Person, caller Class %@", [self class]);
}
}

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

总结:

  1. loadinitialize方法都会在实例化对象之前调用,以main函数为分水岭,前者在main函数之前调用,后者在之后调用。这两个方法会被自动调用,不能手动调用它们。
  2. loadinitialize方法都不用显示的调用父类的方法而是自动调用,即使子类没有initialize方法也会调用父类的方法,而load方法则不会调用父类。
  3. load方法通常用来进行Method Swizzle,initialize方法一般用于初始化全局变量或静态变量。
  4. loadinitialize方法内部使用了锁,因此它们是线程安全的。实现时要尽可能保持简单,避免阻塞线程,不要再使用锁。

iOS load和initialize的区别的更多相关文章

  1. Objective C类方法load和initialize的区别

    Objective C类方法load和initialize的区别   过去两个星期里,为了完成一个工作,接触到了NSObject中非常特别的两个类方法(Class Method).它们的特别之处,在于 ...

  2. oc---类方法load和initialize的区别

    在iOS开发中,就像Application有生命周期回调方法一样,在Objective-C的类被加载和初始化的时候,也可以收到方法回调,可以在适当的情况下做一些定制处理.而这正是本篇文章所要介绍的lo ...

  3. 类方法load和initialize的区别

    1.+load方法当类或分类添加到object-c runtime时被调用,子类的+load方法会在它所有父类的+load方法之后执行,而分类的+load方法会在它的主类的+load方法之后执行.但不 ...

  4. IOS杂笔- 7(类方法load与initialize的区别 浅析)

    在介绍两种类方法之前,NSObject Class Reference里对这两个方法说明: +(void)initialize The runtime sends initialize to each ...

  5. load 和 initialize 的区别

    官方文档 Apple的官方文档很清楚地说明了 initialize 和 load 的区别在于: load 是只要类所在文件被引用就会被调用,而 initialize 是在类或者其子类的第一个方法被调用 ...

  6. load、init和initialize的区别

    在NSObject.h中找到三个方法 + (void)load; + (void)initialize; - (instancetype)init 1. 可知三个方法类型,两个类方法,一个对象方法 2 ...

  7. iOS Load方法 和 initialize方法的比较

    一.load方法特点: 1. 当类被引用进程序的时候会执行这个函数 2.一个类的load方法不用写明[super load],父类就会收到调用,并且在子类之前. 3.Category的load也会收到 ...

  8. load与initialize

    NSObject类有两种初始化方式load和initialize load + (void)load; 对于加入运行期系统的类及分类,必定会调用此方法,且仅调用一次. iOS会在应用程序启动的时候调用 ...

  9. +load 和 +initialize

    APP 启动到执行 main 函数之前,程序就执行了很多代码. 执行顺序: 将程序依赖的动态链接库加载到内存 加载可执行文件中的所有符号,代码 runtime 解析被编译的符号代码 遍历所有的 cla ...

随机推荐

  1. 用于调试的printf函数和自定义log函数

    1. 用宏定义调试用的DPRINT #define DEBUG_ENABLE #ifdef DEBUG_ENABLE #define DPRINT(fmt, args...) fprintf(stde ...

  2. New Concept English Two 18 46

    $课文44  穿过森林 451. Mrs. Anne Sterling did not think of the risk she was taking when she ran through a ...

  3. CF 432D

    http://codeforces.com/problemset/problem/432/D 在前缀是后缀的前提下,求这个前缀在原串中出现了多少次 出现的次数可以用dp求解,前缀是后缀直接用Next判 ...

  4. Python itertools.combinations 和 itertools.permutations 等价代码实现

    最近编程时经常要用到排序组合的代码,想当年还抱着一些情况买了一本<组合数学>,不过现在这货也不知道被自己放哪里了,估计不会是垫桌子腿了吧. 由于去年去东北大学考博面试的时候遇到过可能涉及排 ...

  5. 区间DP的摸索

    (poj真的炸了,以下代码可能有误) 按照下面这个做题顺序,对区间DP不再那么迷了 LOJ1422 是 dp[i][j]=min(dp[i][j],dp[i+1][k-1]+dp[k][j])而不是d ...

  6. 7-19 PAT Judge(25 分)

    The ranklist of PAT is generated from the status list, which shows the scores of the submissions. Th ...

  7. NOIP模拟赛(洛谷11月月赛)

    T1  终于结束的起点 题解:枚举啊... 斐波那契数 第46个爆int,第92个爆long long.... 发现结果一般是m的几倍左右....不用担心T. #include<iostream ...

  8. nyoj A+B Problem IV

    A+B Problem IV 时间限制:1000 ms  |  内存限制:65535 KB 难度:3   描述 acmj最近发现在使用计算器计算高精度的大数加法时很不方便,于是他想着能不能写个程序把这 ...

  9. Tomcat的最大并发数

    日常应用中,单台Tomcat能支持最大的并发数是多少? 作为一个有经验的Java Web开发人员对这个问题应该有大概的印象,并会让问题再具体点,比如Tomcat版本,运行模式,并发请求允许的最大响应时 ...

  10. github之本地上传

    在打算上传到github之前需要在github上面首先创建一个项目(点击右上角“+”号,点击New repository):