Wewnętrzny Block_copy()
nie ma tu zastosowania. To, co chcesz śledzić, to to, czy dany blok żyje na stosie, czy na stercie. Rozważmy następujący kod oparty na przykład:
@interface Foo : NSObject
@end
@implementation Foo
typedef void(^BlockTypedef)(void);
+(void)doSomethingElseWithBlock:(BlockTypedef)block
{
NSLog(@"block=%@", block);
BlockTypedef myBlock = Block_copy(block);
NSLog(@"myBlock=%@", myBlock);
myBlock();
Block_release(myBlock);
}
+(void)doSomethingWithBlock:(BlockTypedef)block
{
[Foo doSomethingElseWithBlock:^() {
block();
}];
}
@end
int main (int argc, const char * argv[])
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
int i = 3;
BlockTypedef block = ^{ printf("i=%d\n", i); };
NSLog(@"block=%@", block);
[Foo doSomethingWithBlock:block];
block();
NSLog(@"block=%@", block);
[pool drain];
return 0;
}
To powinno być ok, ale block
i myblock
są różne rodzaje bloków. block
jest blokiem stosu i ma zasięg stosu wywołującego. Będzie istnieć, dopóki nie zakończy się main()
. myblock
jest blokiem malloc (sterty) i będzie istnieć, dopóki nie zostanie zwolniony. Musisz upewnić się, że nie próbujesz pobrać niekopiowanego odniesienia do block
i użyć go po ukończeniu stosu. Nie można trzymać block
w ivar bez jego kopiowania.
Joachim Bengtsson ma najlepszy opis tego, co znam. @bbum również o tym pisał. (Jeśli bbum błądzi tutaj i mówi, że jestem idiotą, to posłuchaj go, ale myślę, że jestem tutaj.)
Czy spróbować? –
Moja aplikacja nie jest szczególnie dostępna w tym momencie, więc nie. znalazłem to: http://clang.llvm.org/docs/Block-ABI-Apple.txt który mówi „Bloki mogą zawierać Zablokuj wyrażeń dosłownych Wszystkie zmienne stosowane w wewnętrznych bloków są importowane do całej otaczającej Block. zakresy, nawet jeśli zmienne nie są używane. Obejmuje to import const oraz zmienne __block. " Jednak w tym przypadku jest to literał blokowy zawierający blok, a nie kolejność podana tutaj. –