OC底层原码下载
我们知道,iOS的OC底层代码实现是不开源的,我们要想研究其底层的实现原理,就得去Apple open source下载开源的代码。下载地址如下:
- 苹果开源源码汇总: opensource.apple.com
- 更直接的地址:opensource.apple.com/tarballs/
搜索"objc",并选择其中一个版本下载
探索alloc的底层原理实现
全局搜索"alloc {"
这里我们找到了"NSObject"的alloc类方法的实现,然后我们就可以一步一步的跟进去查看底层的实现并分析原理了
alloc
+ (id)alloc {
return _objc_rootAlloc(self);
}
调用了_objc_rootAlloc函数,并将当前类对象作为参数传递进去
_objc_rootAlloc
id
_objc_rootAlloc(Class cls)
{
return callAlloc(cls, false/*checkNil*/, true/*allocWithZone*/);
}
调用了callAlloc函数,将类对象传递进去
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_msgSend,我们只分析_objc_rootAllocWithZone;objc_msgSend很简单,不用多说。
_objc_rootAllocWithZone
id
_objc_rootAllocWithZone(Class cls, malloc_zone_t *zone __unused)
{
// allocWithZone under __OBJC2__ ignores the zone parameter
return _class_createInstanceFromZone(cls, 0, nil,
OBJECT_CONSTRUCT_CALL_BADALLOC);
}
只调用了_class_createInstanceFromZone函数
_class_createInstanceFromZone
这里面调用了3个核心的函数:instanceSize、calloc、initInstanceIsa,这三个函数分别是干什么的呢?
instanceSize
这个函数的返回值是一个size_t的数据,在calloc函数中会用到这个返回值。即请求开辟的内存空间大小,并且开辟的空间大小不小于16。而且调用的了alignedInstanceSize函数来进行字节对齐。即开辟的内存空间大小一定是16字节的整数倍。
calloc
obj = (id)calloc(1, size);
calloc是c语言的函数,表示分配1个size大小的内存空间
initInstanceIsa
inline void
objc_object::initInstanceIsa(Class cls, bool hasCxxDtor)
{
ASSERT(!cls->instancesRequireRawIsa());
ASSERT(hasCxxDtor == cls->hasCxxDtor());
initIsa(cls, true, hasCxxDtor);
}
此函数的作用是将calloc分配的内存和返回的指针地址与类对象进行关联