iOS底层原理 - alloc & init & new 详解

1.准备工作


源码下载:objc4-781 源码编译:可参考教程 源码编译调试

2.源码分析


2.1 alloc源码

源码在手,天下我有!接着就很简单了,创建一个Person类,然后调用 alloc 方法,main.m 如下:

#import <Foundation/Foundation.h>

#import "Person.h"

int main(int argc, const char * argv[]) {

@autoreleasepool {

// insert code here...

Person *objc = [Person alloc];

NSLog(@"Hello, World! %@", objc);

}

return 0;

}

此时,按住command 鼠标左键就可以跳入alloc方法内部了 【第一步】NSObject.mm中的 alloc 实现,可以看到alloc内部调用了一个叫 _objc_rootAlloc 的函数,并传入了当前Person类

+ (id)alloc {

return _objc_rootAlloc(self);

}

【第二步】_objc_rootAlloc内部又调用了 callAlloc() ,同样传入了Person类

id _objc_rootAlloc(Class cls)

{

return callAlloc(cls, false/*checkNil*/, true/*allocWithZone*/);

}

【第三步】callAlloc函数内部

static ALWAYS_INLINE id

callAlloc(Class cls, bool checkNil, bool allocWithZone=false)

{

#if __OBJC2__

if (slowpath(checkNil && !cls)) return nil;

if (fastpath(!cls->ISA()->hasCustomAWZ())) {

return _objc_rootAllocWithZone(cls, nil);

}

#endif

// No shortcuts available.

if (allocWithZone) {

return ((id(*)(id, SEL, struct _NSZone *))objc_msgSend)(cls, @selector(allocWithZone:), nil);

}

return ((id(*)(id, SEL))objc_msgSend)(cls, @selector(alloc));

}

到了这里,函数出现了分支。因此,在流程判断上,就会复杂一些不过,我们编译了源码,根据断点很容易判断流程走了 objc_rootAllocWithZone() 函数 这里解释下为什么会走 _objc_rootAllocWithZone() ? 我们的 NSObject 类经历过改版,原本会调用allocWithZone:方法,改版后去掉了。 【第四步】

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值