2013-02-04 4 views
5

Secondo il dossier Block_private.h, ogni volta che un blocco è dichiarata in un file di Objective-C, le seguenti strutture vengono creati nel file oggetto di rappresentarlo:Perché questo blocco non ha copia e dispose i puntatori nel suo descrittore?

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

Tuttavia, quando ho generare un file di assiemi, con clang -S ..., da

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

ottengo il seguente frammento che rappresenta il blocco:

.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 

Quindi, __block_literal_global e __block_descriptor_tmp sono un Block_layout e un Block_descriptor, rispettivamente. Ma, come puoi vedere, il terzo campo di __block_descriptor_tmp, che dovrebbe essere un void (*copy)(void *dst, void *src) secondo Block_private.h, è un const char * che punta alla codifica del tipo di blocco.

La mia domanda è: come si presenta una struttura descrittore di blocchi, esattamente? Il mio file Block_private.h è deprecato, pertanto l'implementazione di Block_descriptor è attualmente diversa da quella che ho presentato? Se il mio file è corretto, perché il terzo campo è __block_descriptor_tmp a const char *, non è un void (*copy)(void *dst, void *src)?

risposta

6

la copia e smaltire aiutanti sono inclusi solo se il blocco ha cattura che devono essere gestite (In pratica: Oggetti & __block VAR)

Se sono presenti poi block->flags & BLOCK_HAS_COPY_DISPOSE

Tutto quello che c'è da sapere è delineato qui: http://clang.llvm.org/docs/Block-ABI-Apple.html

+0

Oh, sì! Quindi, nel mio caso, le funzioni di helper opzionali non erano presenti, quindi il terzo campo di '__block_descriptor_tmp' corrisponde al campo firma di' struct Block_descriptor_1' e il quarto campo è la fine della matrice terminata da NULL di variabili importate. Dato che non esiste una variabile importata, c'è solo un NULL alla fine di '__block_descriptor_tmp'. Ho ragione? – LuisABOL

+0

Il terzo campo è la firma sì, ma il campo NULL è per i metadati della garbage collection, che non è utilizzato nel runtime moderno. I vars catturati si trovano nel block_literal, non nel descrittore (il descrittore è condiviso tra tutte le istanze del blocco, mentre un nuovo letterale è assegnato a ciascuno) –

+0

Oh, naturalmente. Ci scusiamo per l'ultima parte. Ero pazzo! Grazie! – LuisABOL