iOS日常须知iOS底层

深入理解iOS中load方法和initialize方

2016-05-18  本文已影响1967人  小小呆瓜渺小的程序员

                         深入理解iOS中load方法和initialize方法

      在ios面试的时候,面试官经常会问load方法和initalize方法有什么区别和共同点。接下来我们就理解一下这两个方法。

首先来看看苹果官方文档对这两个方法的说明: 

initialize:The runtime sends initialize to each class in a program just before the class, or any class that inherits from it, is sent its first message from within the program.

load:Invoked whenever a class or category is added to the Objective-C ,runtime; implement this method to perform class-specific behavior upon loading.

表面意思就是说:initialize方法是在第一次调用该类的方法的时候调用,load方法是在程序启动之前就调用,父类先于子类执行,类先于分类执行。

@interface ParentClass : NSObject

@end

@interface ChildClass : NSObject

@end

@interface OtherClass : NSObject

-(void)completeMethod;

@end

@implementation ParentClass

+(void) initialize{

NSLog(@"%@  %s",[self class], __FUNCTION__);

}

+(void) load{

NSLog(@"%@  %s",[self class], __FUNCTION__);

}

@end

@implementation ChildClass

+(void) initialize{

NSLog(@"%@  %s",[self class],__FUNCTION__);

OtherClass *other = [[OtherClass alloc] init];

[other completeMethod];

}

@end

@implementation OtherClass

-(void)completeMethod{

NSLog(@"%@  %s",[self class], __FUNCTION__);

}

+(void) load{

NSLog(@"%@ %s",[self class], __FUNCTION__);

}

+(void) initialize{

NSLog(@"%@ %s",[self class], __FUNCTION__);

}

@end

说明:一个ParentClass类实现了+(void)load和+(void)initialize方法,ChildClass继承于ParentClass只重写了initialize方法,OtherClass类重写了+(void)load和+(void)initialize方法,ChildClass的initialize方法中构建了一个OtherClass类对象,在方法的实现中只打印了当前的类名和方法名。

我们首先在工程中只是引入这些类,而不去使用他们,运行之后的结果:

ParentClass  +[ParentClass initialize]

ParentClass  +[ParentClass load]

OtherClass +[OtherClass initialize]

OtherClass +[OtherClass load]

就像Apple文档所说的那样,只要有引用runtime就会去调用类的+(void)load方法,从输出可以看出ParentClass的+(void)initialize方法也调用了,而且是在initialize方法之前,那是因为在+(void)load方法中调用了[self class]方法,这个方法触发了initialize方法的执行。load和initialize方法都不需要手动的去调用super方法,父类的执行顺序在子类之前。当在程序中把所有的[self class]删除之后,initialize方法都不会调用。

总结:

1.load和initialize都会在实例化对象之前调用,以main函数为分水岭,前者是在main函数之前,后者是在main函数之后。

2.load和initialize方法都不会显示的调用父类的方法而是自动调用,即使子类没有initialize方法也会调用父类的方法,load方法不会调用父类。

3.load和initialize方法内部使用了锁,因此他们是线程安全的,实现时要尽可能简单,避免线程阻塞,不要再次使用锁。

4.load方法常用来method swizzle,initialize常常用于初始化全局变量和静态变量.

上一篇下一篇

猜你喜欢

热点阅读