美文网首页
iOS之OC底层alloc流程

iOS之OC底层alloc流程

作者: 无极战思 | 来源:发表于2021-06-07 18:38 被阅读0次

引言

在实际iOS开发中我,我们经常会调用alloc 方法,然而对于alloc方法的底层实现原理,大部分人并不是很清楚。

一、准备工作

1、探究底层,肯定要阅读苹果源码。源码库的下载地址:opensource或者 Source Browser, 两者的区别在于Source Browser里面的版本更新更快更详细,搜索objc4即得到我们索要下载的源码。

image.png image.png

2.源码编译:这里暂不讨论,有兴趣的可以自己百度查资料,这里推荐cooci大神的github地址:https://github.com/LGCooci?tab=repositories,里面有各种版本的更新和步骤。

二、alloc流程图结果

如下:

image.png

那么,究竟上面的流程图是怎样出来的呢?我们都知道,正常情况项目里面的这些方法名我们是不知道的,那么,探究流程图的思路是什么,需要具备哪方面的知识?

三、alloc流程图探索过程

(1)首先我们需要了解一个概念:符号断点。在我们对底层alloc源码一无所知的情况下,我们只知道创建对象要alloc,我们就已alloc方法为突破口

alloc.gif
这里需要注意的是,需要先进入到你想要看的断点,再把符号断点打开,切记切记。点step into键的时候需要同时按住control键 image.png

在这里可以发现代码进入了objc_alloc继续点击step into还会进入一些底层的其它方法,这里不做详细介绍。

(2)通过反汇编调试


alloc反汇编.gif image.png

还是先运行到断点处,再打开汇编,继续点击step into+control键可以从汇编里面看出,走了objc_alloc方法。
(3)看源码,是最直观的方法,推荐大家使用。

alloc源码流程.gif

核心代码:

static ALWAYS_INLINE id _class_createInstanceFromZone(Class cls, size_t extraBytes, void *zone,
                          int construct_flags = OBJECT_CONSTRUCT_NONE,
                          bool cxxConstruct = true,
                          size_t *outAllocatedSize = nil)
 {
  ASSERT(cls->isRealized());

  // Read class's info bits all at once for performance
  bool hasCxxCtor = cxxConstruct && cls->hasCxxCtor();
  bool hasCxxDtor = cls->hasCxxDtor();
  bool fast = cls->canAllocNonpointer();
   size_t size;
  //先计算内存空间所需要的大小,在这个过程中遵循着内存对齐规则,以8字节为单位,因为我们的基本数据类型是不会超过8个字节的,最主要地是,以空间换时间,让cpu保持高效。
size = cls->instanceSize(extraBytes);
if (outAllocatedSize) *outAllocatedSize = size;

id obj;
//alloc:向栈申请开辟内存,返回地址指针
if (zone) {
    obj = (id)malloc_zone_calloc((malloc_zone_t *)zone, 1, size);
} else {
    obj = (id)calloc(1, size);
}
if (slowpath(!obj)) {
    if (construct_flags & OBJECT_CONSTRUCT_CALL_BADALLOC) {
        return _objc_callBadAllocHandler(cls);
    }
    return nil;
}

if (!zone && fast) {
//将申请的内存地址指针和isa指针即我们的类绑定起来
    obj->initInstanceIsa(cls, hasCxxDtor);
} else {
    // Use raw pointer isa on the assumption that they might be
    // doing something weird with the zone or RR.
    obj->initIsa(cls);
}

if (fastpath(!hasCxxCtor)) {
    return obj;
}

construct_flags |= OBJECT_CONSTRUCT_FREE_ONFAILURE;
return object_cxxConstructFromClass(obj, cls, construct_flags);
}

相关文章

网友评论

      本文标题:iOS之OC底层alloc流程

      本文链接:https://www.haomeiwen.com/subject/rpiviktx.html