consideri il codice seguente:Qualora un blocco letterale Retain riferimento blocchi di heap allocati
// t included so block1 is a stack block. See [1] below
int t = 1;
SimpleBlock block1 = ^{ NSLog(@"block1, %d", t); };
// copy block1 to the heap
SimpleBlock block1_copied = [block1 copy];
// block2 is allocated on the stack, and refers to
// block1 on the stack and block1_copied on the heap
SimpleBlock block2 = ^{
NSLog(@"block2");
block1_copied();
block1();
};
[block1_copied release];
// When the next line of code is executed, block2_copied is
// allocated at the same memory address on on the heap as
// block1_copied, indicating that block1_copied has been
// deallocated. Why didn't block2 retain block1_copied?
SimpleBlock block2_copied = [block2 copy];
block2_copied();
[block2_copied release];
Qualora, per completezza, SimpleBlock è definita da:
typedef void (^SimpleBlock)(void);
Come indicato dal commento nel codice , i miei test (usando sia GCC 4.2 che LLVM 2.0) mostrano che block1_copied è deallocato dal momento in cui viene chiamata [block2 copy], ma secondo la documentazione che ho letto [1,3], i blocchi sono oggetti e blocchi obiettivo-c conservare gli oggetti obiettivo-c a cui si riferiscono [2] (nella variabile non di istanza c ase).
Inoltre, quando il blocco2 viene copiato, il suo riferimento al blocco1 viene anche modificato in un riferimento a una nuova copia del blocco1 (che è diverso da block1_copied), come previsto, poiché i blocchi copiano tutti i blocchi a cui fanno riferimento [ 2].
Quindi, cosa sta succedendo qui?
A) Se i blocchi conservano oggetti obiettivo-c a cui fanno riferimento e i blocchi sono oggetti obiettivo-c, perché viene bloccato deal1_copied prima che il blocco2 esca dall'ambito?
B) Se i blocchi copiano blocchi a cui fanno riferimento, e se l'invio - (id) copia su un blocco con allocazione heap in realtà incrementa semplicemente il conteggio di mantenimento, perché viene bloccato deal1_copied prima che block2 esca dall'ambito?
C) Se questo è il comportamento previsto, dove è la documentazione che lo spiega?
[1] http://cocoawithlove.com/2009/10/how-blocks-are-implemented-and.html
[2] http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/Blocks/Articles/bxVariables.html
[3] http://clang.llvm.org/docs/BlockLanguageSpec.txt
Nota: Nel mio test, il risultato dell'esecuzione di questo codice è una chiamata infinitamente ricorsiva a block2_copied(), dal momento che block1_copied() aveva lo stesso indirizzo di memoria di block2_copied.
+1 interessante .... –