美文网首页
002-iOS alloc、init探索

002-iOS alloc、init探索

作者: A慢慢懂 | 来源:发表于2020-09-09 16:08 被阅读0次

探索之前我们先来看个例子


image.png

如上图所示,用了%@和%p,打印输出对象,结果输出的同样的结果,但是打印输出&对象就不一样了呢?
cars1对象用了alloc,开辟了内存空间,cars2和cars3是用cars init的结果,三个指针对象,指向了同一个块内存空间,但是指针对象本身的地址是不一样的。这就类似办公室里面共有一台打印机,但是拥有打印机的每个个体都是不一样的。&取地址

  • alloc开辟内存空间,而init不会开辟
  • 指向同一块内存空间的指针,指针本身的地址不一定相同
  • 栈内存是连续开辟的,指针本身所占的字节为8bit

一、alloc的流程

1.1初步流程
初步流程.jpg
1.2完整流程

准备一份含有objc源码的项目,链接https://github.com/zhaimengting/objc4
接着上面的流程呢,我们再深入了解下。
_objc_rootAllocWithZone深入是什么呢?

objcAllocNext.gif

此时流程图为


15995572971930.jpg

1.2.1 cls->instanceSize 开辟多少内存
双击cls->instanceSize,选择Jump to definition
进入

size_t instanceSize(size_t extraBytes) const {
        if (fastpath(cache.hasFastInstanceSize(extraBytes))) {
            return cache.fastInstanceSize(extraBytes);
        }

        size_t size = alignedInstanceSize() + extraBytes;
        // CF requires all objects be at least 16 bytes.
        if (size < 16) size = 16;
        return size;
    }
  • if(fastpath(cache.hasFastInstanceSize(extraBytes)))
    为ture时,返回cache.fastInstanceSize(extraBytes),进入fastInstanceSize(extraBytes)
    size_t fastInstanceSize(size_t extra) const
    {
        ASSERT(hasFastInstanceSize(extra));

        if (__builtin_constant_p(extra) && extra == 0) {
            return _flags & FAST_CACHE_ALLOC_MASK16;
        } else {
            size_t size = _flags & FAST_CACHE_ALLOC_MASK;
            // remove the FAST_CACHE_ALLOC_DELTA16 that was added
            // by setFastInstanceSize
            return align16(size + extra - FAST_CACHE_ALLOC_DELTA16);
        }
    }
15996294040168.jpg
extra值为0,返回align16(size + extra - FAST_CACHE_ALLOC_DELTA16)
objcalgin16.gif
static inline size_t align16(size_t x) {
    return (x + size_t(15)) & ~size_t(15);
}

size_t x = 32;

32(二进制) =0000 0000 0010 0000;
15(二进制) =0000 0000 0000 1111;
47(二进制) =0000 0000 0010 1111;
~15(二进制) =0000 0000 1111 0000;
47&(~15) =0000 0000 0010 0000;

size_t align16主要作用是16位内存对齐
1.2.2 calloc 开辟内存的地址
obj = (id)calloc(1, size);

void    *calloc(size_t __count, size_t __size) __result_use_check __alloc_size(1,2);
  1. size_t __count 开辟内存空间的个数
  2. size_t __size 所开辟内存的大小
    15996343883250.jpg

1.2.3 obj->initInstanceIsa 将对象的isa指针指向开辟的内存空间地址

15996373765418.jpg

总结上面内容入下表

cls->instanceSize 先计算出需要的内存空间大小
calloc 向系统申请开辟内存,返回地址指针
obj->initInstanceIsa 关联到相应的类

二、init的探索

在含有alloc函数的NSObject.mm中搜索init{

+ (id)init {
    return (id)self;
}

构造方法返回self。
那么与new又有什么区别呢?

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

实质上没有什么区别,但是有时候我们会在类里面重写init方法,如果用new方法的话,不会走init重写方法,尽量不用new。

相关文章

  • 002-iOS alloc、init探索

    探索之前我们先来看个例子 如上图所示,用了%@和%p,打印输出对象,结果输出的同样的结果,但是打印输出&对象就不一...

  • alloc init探索

    1、alloc init 首先用alloc生成一个LGPerson对象。在init另外的对象。 输出生成的对象信息...

  • alloc & init 探索

    首先创建一个对象 p1,p2,p3 打印结果结果 那么问题来了 alloc 做了什么?init 做了什么?上面的打...

  • iOS alloc & init 探索

    0x000 从哪里入手? 先看看main函数 0x001 初探? 为什么是 alloc init? alloc i...

  • iOS alloc & init 探索

    初探 1、新建一个Person 类 先思考打印情况 再运行 得到结果为 猜测:1、init 没有对内存进行任何...

  • alloc&init探索

    OC底层原理学习 alloc 初探 首先创建一个继承于NSObject的Person类带着以下几个疑问,查看打印结...

  • alloc&init探索

    main函数的加载流程 1.在int main前面打个断点 然后增加一个_objc_init的符号断点 记得关闭左...

  • alloc与init探索

    知识点概要 引入alloc干了什么?为什么要有init?为什么要有new?直接使用有何缺陷?[NSObject a...

  • alloc&init 探索

    alloc&init 探索 首先要明确alloc做了什么,init做了什么。 上方的p1/p2/p3经打印是一模一...

  • 1.对象原理探究

    alloc 探索 alloc 已经创建了对象 init alloc 实现 原理 源码实现 介绍三种方式 1、下断点...

网友评论

      本文标题:002-iOS alloc、init探索

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