5

ファイルによると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はそれぞれ aBlock_layoutと aBlock_descriptorです。しかし、ご覧のとおり、 の 3 番目のフィールド (__block_descriptor_tmpvoid (*copy)(void *dst, void *src)よるとBlock_private.h) はconst char *、ブロックの型エンコーディングを指す です。

私の質問は次のとおりです。ブロック記述子構造は正確にはどのように見えますか? 私のBlock_private.hファイルは推奨されていないので、Block_descriptor現在の実装は私が提示したものとは異なりますか? ファイルが正しければ、なぜ 3 番目のフィールドが__block_descriptor_tmpではconst char *なく なのvoid (*copy)(void *dst, void *src)ですか?

4

1 に答える 1

7

copy および dispose ヘルパーは、ブロックに管理が必要なキャプチャがある場合にのみ含まれます (実際には、オブジェクトと __block 変数)。

それらが存在する場合block->flags & BLOCK_HAS_COPY_DISPOSE

知っておくべきことはすべてここで概説されています: http://clang.llvm.org/docs/Block-ABI-Apple.html

于 2013-02-04T02:09:57.003 に答える