美文网首页
OC对象原理-alloc的探索

OC对象原理-alloc的探索

作者: 我要当个程序员 | 来源:发表于2020-09-04 10:48 被阅读0次

    1. 用到的软硬件

    • Macbook Air
    • iPhone8手机一枚
    • macOS Mojave 10.14.6
    • Xcode 11.3.1
    • Object-C(编程语言)

    2. 为什么实例化一个对象总要[[xxx alloc] init]

    你会不会有这样的疑问,那我们一起先从alloc入手一步一步来探究,首先打开xcode->创建工程项目。如图


    1.png 2.png 3.png

    在我们下面代码处打上段点

    ViewController *vc = [ViewController alloc];
    

    然后点击运行,运行成功断点会卡在我们打断点的位置。如图

    5.png
    这里按住control这个时候横线会变成小圆点,然后在点击会发现我们跳入到了objc_alloc这个方法
    4.png

    由于这个方法是底层里面的方法,我们这里并不能获得,所以我们需要这个时候我们在这里打上一个符号断点(Symbolic Breakpoint),输入objc_alloc,会发现我们的alloc的实现方法来自于libobjc.A.dylib这个库里面(libobjc.A.dylib对应于官方给的objc4这个源码库里面)

    12.png 13.png

    3. 下载探究alloc的源码和实现

    这个时候我们在去按住cmd就可以跳到原生方法里面,看到它是如何实现的。


    15.jpg

    其他的都不重要,最后我们的alloc回调来自_class_createInstanceFromZone这个方法里面看看它是如何实现的。

    16.png

    通过测试下来,发现最主要三种方法来实现我们的alloc的操作
    1、cls->instanceSize
    2、calloc
    3、obj->initInstanceIsa
    那么这三种方法分别做了什么呢?

    17.jpg

    3. init和new做了什么?

    查看我们的源代码可以找到init()的实现方法

    - (id)init {
        return _objc_rootInit(self);
    }
    
    id
    _objc_rootInit(id obj)
    {
        return obj;
    }
    

    好尴尬,这个init什么事情都没有做,那么我们为什么总是会
    LGPerson *objc = [[LGPerson alloc] init];岂不是只要
    LGPerson *objc = [LGPerson alloc];
    其实是可以的,但是有的人习惯在init里面重新写东西比如

    -(id)init(){
      self.xx = xxxxx;
      self.xx = xxxxx;
      ...
    }
    

    所以建议你还是带上init

    在看看new()的方法

    + (id)new {
        return [callAlloc(self, false/*checkNil*/) init];
    }
    

    可以出来,这个new相当于 alloc+init;

    4. 总结

    alloc用来开辟系统内存。init什么也没有干,new则是alloc+init。
    这里有我写的一篇关于fastpath和slowpath片解

    相关文章

      网友评论

          本文标题:OC对象原理-alloc的探索

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