第三篇: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

WechatIMG1913.jpeg
然后我们把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方法其实其实一个工厂模拟,我们之前篇章也说过,我们看下什么是工厂模式:
工厂模式:工厂模式就是我们在创建对象时不会对客户端暴露创建逻辑,并且是通过使用一个共同的接口来指向新创建的对象。

优点:一个调用者想创建一个对象,只要知道其名称就可以了。
     扩展性高,如果想增加一个产 品,只要扩展一个工厂类就可以。
     屏蔽产品的具体实现,调用者只关心产品的接口。
缺点:每次增加一个产品时,都需要增加一个具体类和对象实现工厂,使得系             
     统中类的个数成倍增加,在一定程度上增加了系统的复杂度,同时也增加          
     了系统具体类的依赖。这并不是什么好事。
上一篇下一篇

猜你喜欢

热点阅读