第三篇:iOS底层探索init和new
2022-04-20 本文已影响0人
坚持才会看到希望
首先我先来看段代码:
@implementation HPWPerson
-(instancetype)init {
if (self = [super init]) {
self.name = @"HPW";
}
return self;
}
@end
int main(int argc, char * argv[]) {
NSString * appDelegateClassName;
@autoreleasepool {
// Setup code that might create autoreleased objects goes here.
appDelegateClassName = NSStringFromClass([AppDelegate class]);
// 工厂模式 --
HPWPerson *p1 = [[HPWPerson alloc] init]; //
HPWPerson *p2 = [HPWPerson new];
NSLog(@"%@ %@",p1.name,p2.name);
}
return UIApplicationMain(argc, argv, nil, appDelegateClassName);
}
进过上面两个代码后,其输出为:
2022-04-20 22:59:38.927503+0800 003--init与new[62347:1144463] HPW HPW
我们发现通过new方法也可以调用init方法,这个是为什么呢,我们去通过苹果源码来分析下,通过源码我们了解到,其实调用了new方法也就是调用了callAlloc方法,callAlloc方法我们在之前探究alloc底层的时候又讲到,new可以理解是alloc+init,那我们如何去验证呢?
// alloc + init
+ (id)new {
return [callAlloc(self, false/*checkNil*/) init];
}
我们先把进行汇编调试,发现其会跳到断点处,其有个注释为symbol stub for: objc_opt_new
然后我们把objc_opt_new这个在苹果的源码里进行一个搜索如下:所以知道new是alloc+init组合,在源码中就验证了这个 [callAlloc(cls, false/checkNil/) init]。
//new alloc + init
id
objc_opt_new(Class cls)
{
#if __OBJC2__
if (fastpath(cls && !cls->ISA()->hasCustomCore())) {
return [callAlloc(cls, false/*checkNil*/) init];
}
#endif
return ((id(*)(id, SEL))objc_msgSend)(cls, @selector(new));
}
init方法其实其实一个工厂模拟,我们之前篇章也说过,我们看下什么是工厂模式:
工厂模式:工厂模式就是我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。
优点:一个调用者想创建一个对象,只要知道其名称就可以了。
扩展性高,如果想增加一个产 品,只要扩展一个工厂类就可以。
屏蔽产品的具体实现,调用者只关心产品的接口。
缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系
统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加
了系统具体类的依赖。这并不是什么好事。