为什么这个Block没有在其描述符中复制和处理指针?

时间:2013-02-04 02:03:18

标签: objective-c compilation objective-c-blocks

根据Block_private.h文件,无论何时在Objective-c文件中声明块,都会在目标文件中创建以下结构来表示它:

struct Block_descriptor {
    unsigned long int reserved;
    unsigned long int size;
    void (*copy)(void *dst, void *src);
    void (*dispose)(void *);
};

struct Block_layout {
    void *isa;
    int flags;
    int reserved; 
    void (*invoke)(void *, ...);
    struct Block_descriptor *descriptor;
    /* Imported variables. */
};

然而,当我使用clang -S ...

生成一个程序集文件时
int(^squared)(int) = ^(int i) {
    return i*i;
};

我得到以下代表该块的代码段:

    .type   .L.str210,@object       # @.str210
.L.str210:
    .asciz   "i12@?0i8"
    .size   .L.str210, 9

    .type   __block_descriptor_tmp,@object # @__block_descriptor_tmp
    .section    .rodata,"a",@progbits
    .align  16
__block_descriptor_tmp:
    .quad   0                       # 0x0
    .quad   32                      # 0x20
    .quad   .L.str210
    .quad   0
    .size   __block_descriptor_tmp, 32

    .type   __block_literal_global,@object # @__block_literal_global
    .align  8
__block_literal_global:
    .quad   _NSConcreteGlobalBlock
    .long   1342177280              # 0x50000000
    .long   0                       # 0x0
    .quad   __main_block_invoke
    .quad   __block_descriptor_tmp
    .size   __block_literal_global, 32

因此,__block_literal_global__block_descriptor_tmp分别是Block_layoutBlock_descriptor。但是,正如您所看到的,__block_descriptor_tmp的第三个字段(根据void (*copy)(void *dst, void *src)应为Block_private.h)是const char *,指向块的类型编码。< / p>

我的问题是:块描述符结构究竟是什么样的?我的Block_private.h文件是否已被弃用,因此Block_descriptor实施目前与我提交的文件不同?如果我的文件是正确的,为什么__block_descriptor_tmp的第三个字段是const char *,而不是void (*copy)(void *dst, void *src)

1 个答案:

答案 0 :(得分:6)

只有当块具有需要管理的捕获时才包含复制和配置助手(实际上说:对象&amp; __block变量)

如果它们存在,那么block->flags & BLOCK_HAS_COPY_DISPOSE

此处列出了您需要了解的所有内容:http://clang.llvm.org/docs/Block-ABI-Apple.html