Block底层探索3 ——Block_layout的结构

在上一篇_Block_copy方法中可以看到block实际的数据结构为Block_layout结构体。

struct Block_layout {
    void * __ptrauth_objc_isa_pointer isa;
    volatile int32_t flags; // contains ref count
    int32_t reserved;
    BlockInvokeFunction invoke;
    struct Block_descriptor_1 *descriptor;
    // imported variables
};

查看Block_descriptor_1的结构体,发现了Block_descriptor_2和Block_descriptor_3结构体。

#define BLOCK_DESCRIPTOR_1 1
struct Block_descriptor_1 {
    uintptr_t reserved;
    uintptr_t size;
};

#define BLOCK_DESCRIPTOR_2 1
struct Block_descriptor_2 {
    // requires BLOCK_HAS_COPY_DISPOSE
    BlockCopyFunction copy;
    BlockDisposeFunction dispose;
};

#define BLOCK_DESCRIPTOR_3 1
struct Block_descriptor_3 {
    // requires BLOCK_HAS_SIGNATURE
    const char *signature;
    const char *layout;     // contents depend on BLOCK_HAS_EXTENDED_LAYOUT
};

这两个结构体应该就是上面imported variables可能会有的内容了。
可以看到三者个功能不同,Block_descriptor_2里有block的copy函数和dispose函数,Block_descriptor_3里存放了signature签名等信息。

全局搜索Block_descriptor_2发现相关代码

static struct Block_descriptor_2 * _Block_descriptor_2(struct Block_layout *aBlock)
{
    uint8_t *desc = (uint8_t *)_Block_get_descriptor(aBlock);
    desc += sizeof(struct Block_descriptor_1);
    return (struct Block_descriptor_2 *)desc;
}

static struct Block_descriptor_3 * _Block_descriptor_3(struct Block_layout *aBlock)
{
    uint8_t *desc = (uint8_t *)_Block_get_descriptor(aBlock);
    desc += sizeof(struct Block_descriptor_1);
    if (aBlock->flags & BLOCK_HAS_COPY_DISPOSE) {
        desc += sizeof(struct Block_descriptor_2);
    }
    return (struct Block_descriptor_3 *)desc;
}

可以看到Block_descriptor_2和Block_descriptor_3的生成过程:
1.Block_descriptor_2是在Block_descriptor_1所占内存末位添加Block_descriptor_2大小的结构体。
2.Block_descriptor_3判断如果没有Block_descriptor_2的话,重复步骤1的过程。如果有Block_descriptor_2,就再往下在Block_descriptor_2的末尾添加Block_descriptor_3。

©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容