OK, odszedłem i grałem z Xcode przez chwilę, a oto model tego, co się dzieje, wydaje się pasować do tego, co widzę.
Blok użyłem powyżej nie robi nic szczególnego, ale enumerateObjectsUsingBlock
kod wydaje się mieć swój własny NSAutoreleasePool
, tak że wydaje się, co było przyczyną dealloc
być wywołane na obiektach alloc'ed
, ale autoreleased wewnątrz bloku.
Poniższy kod pasuje do zachowania tego, co widzę powyżej:
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
// simple block test - just iterate over some items and
// add them to a string
typedef void (^AccArrayBlock)(id obj, int idx, BOOL *stop);
// items to 'process'
NSArray *items = [NSArray arrayWithObjects:@"why ", @"must ", @"this ",nil];
int idx = 0;
BOOL doStop = NO;
// make sentence mutable, so we can assign it inside block
__block NSString *sentence = @"";
// make a similar block to what we'd pass to enumerate...
AccArrayBlock myBlock = ^(id obj, int idx, BOOL *stop)
{
// returns and assigns an autoreleased string object
sentence = [sentence stringByAppendingFormat:@"(%d) %@ ",idx,obj];
};
// enumerate items and call block
for (NSString *item in items) {
// create a pool to clean up any autoreleased objects in loop
// remove this line, and the sentence will be valid after loop
NSAutoreleasePool *innerPool = [[NSAutoreleasePool alloc] init];
myBlock(item, idx++, &doStop);
// drain the pool, autorelease objects from block
[innerPool drain];
if (doStop) {
break;
}
}
// faults if we drained the pool
// Program received signal: “EXC_BAD_ACCESS”.
NSLog(@"Sentence is %@",sentence);
[pool drain];
return 0;
}
Jeśli usunąć obiekt innerPool
, wówczas kod działa tak jak pierwotnie zakładano, a przypuszczalnie basen NSRunLoop
końcu posprzątać różne obiekty NSString
.
UWAGA: Ten wątek jest teraz numer 2 Google wynik dla 'autorelease enumerateObjectsUsingBlock':
Google 'enumerateObjectsUsingBlock+autorelease'
Pierwszy wynik potwierdza tę odpowiedź. Dziękuje wszystkim.
Wow, to dziwne, nie jestem pewien, dlaczego to nie działa. – jtbandes
Widziałem, jak ludzie wykonują autorelease '[[someVariable retain]] na końcu bloków, aby zwrócić rzeczy, ale nie jestem pewien, dlaczego to miałoby znaczenie, jeśli podejrzewam, że uruchamiana jest pula autorelease. Nie wiem jednak, dlatego pytam, i są wszelkiego rodzaju artykuły na temat kopiowania bloków i przekazywania ich, ale nic, co mogę znaleźć na czymś, co powinno być proste, jak to. –
Jaki jest błąd/wyjątek, który otrzymujesz? – nacho4d