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)
?
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
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) –
Oh, naturalmente. Ci scusiamo per l'ultima parte. Ero pazzo! Grazie! – LuisABOL