![](https://img.haomeiwen.com/i2020276/2dcec0ca3bedb48e.png)
// Call [cls alloc] or [cls allocWithZone:nil], with appropriate
// shortcutting optimizations.
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));
}
#define fastpath(x) (__builtin_expect(bool(x), 1))
#define slowpath(x) (__builtin_expect(bool(x), 0))
__builtin_expect(exp, n)
方法表示 exp
很有可能为 0,返回值为 exp
。你可以将 fastpath(x)
理解成真值判断,slowpath(x)
理解成假值判断。
所以,根据传入值,checkNil
为 false,checkNil && !cls
也为 false。那么这里不会返回 nil。
这个判断 if (fastpath(!cls->ISA()->hasCustomAWZ())),这是判断是_objc_rootAllocWithZone ---> _class_createInstanceFromZone ---> 分配对象空间。
init 和 new的区别
+ (id)alloc {
return _objc_rootAlloc(self);
}
id _objc_rootAlloc(Class cls)
{
return callAlloc(cls, false/*checkNil*/, true/*allocWithZone*/);
}
+ (id)new {
return [callAlloc(self, false/*checkNil*/) init];
//[[self alloc] init]
}
[[NSObject alloc] init]与[NSObject new]本质上并没有什么区别,只是在分配内存上面一个显式的调用了alloc,一个隐式调用。并且前者还可以调用自定义的一些其他init方法,而后者只能调用init方法。
网友评论