2013-02-04 19 views
5

Theo Block_private.h tập tin, bất cứ khi nào một khối được khai báo trong một tập tin Objective-C, các cấu trúc sau đây được tạo ra trong file đối tượng để đại diện cho nó:Tại sao Block này không sao chép và hủy bỏ con trỏ trong bộ mô tả của nó?

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. */ 
}; 

Tuy nhiên, khi tôi tạo ra một file lắp ráp, với clang -S ..., từ

int(^squared)(int) = ^(int i) { 
    return i*i; 
}; 

tôi nhận được đoạn mã sau đây đại diện cho khối:

.type .L.str210,@object  # @.str210 
.L.str210: 
    .asciz "[email protected]?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 

Vì vậy, __block_literal_global__block_descriptor_tmp tương ứng là Block_layoutBlock_descriptor. Nhưng, như bạn có thể thấy, trường thứ ba của __block_descriptor_tmp, phải là void (*copy)(void *dst, void *src) theo Block_private.h, là const char * trỏ đến mã hóa loại của khối.

Câu hỏi của tôi là: cấu trúc mô tả khối trông như thế nào, chính xác? Tệp tin Block_private.h của tôi có được chấp nhận không, do đó việc triển khai Block_descriptor hiện có khác với triển khai tôi đã trình bày không? Nếu tệp của tôi đúng, tại sao trường thứ ba là __block_descriptor_tmp a const char *, không phải là void (*copy)(void *dst, void *src)?

Trả lời

6

Bản sao và xử lý những người giúp đỡ chỉ được bao gồm nếu block còn có ảnh chụp mà cần phải được quản lý (Thực tế mà nói: đối tượng & __block vars)

Nếu họ có mặt sau đó block->flags & BLOCK_HAS_COPY_DISPOSE

Tất cả những gì bạn cần biết được nêu ở đây: http://clang.llvm.org/docs/Block-ABI-Apple.html

+0

Ồ, vâng! Vì vậy, trong trường hợp của tôi, các hàm trợ giúp tùy chọn không có mặt, do đó trường thứ ba '__block_descriptor_tmp' tương ứng với trường chữ ký' struct Block_descriptor_1' và trường thứ ra là kết thúc của mảng được kết thúc NULL của các biến được nhập. Vì không có biến được nhập, chỉ có NULL ở cuối '__block_descriptor_tmp'. Tôi có đúng không? – LuisABOL

+0

Trường thứ ba là chữ ký có, nhưng trường NULL là cho siêu dữ liệu thu thập rác, không được sử dụng trong thời gian chạy hiện đại. Các vars đã chụp nằm trong block_literal, không phải bộ mô tả (bộ mô tả được chia sẻ giữa tất cả các trường hợp của khối, trong khi một chữ cái mới được phân bổ cho mỗi khối) –

+0

Ồ, tất nhiên. Xin lỗi cho phần cuối cùng. Tôi bị điên! Cảm ơn bạn! – LuisABOL