Ok, tôi đã đi và chơi với Xcode một chút, và đây là một mô hình của những gì đang xảy ra, mà dường như phù hợp với những gì tôi nhìn thấy.
Khối tôi đã sử dụng trên là không làm bất cứ điều gì đặc biệt, nhưng enumerateObjectsUsingBlock
mã xuất hiện để có riêng của mình NSAutoreleasePool
, do đó có vẻ là những gì đã gây dealloc
được gọi trên đối tượng alloc'ed
, nhưng autoreleased bên trong khối.
Các mã sau đây phù hợp với hành vi những gì tôi nhìn thấy ở trên:
#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;
}
Nếu tôi loại bỏ các đối tượng innerPool
, sau đó mã hoạt động như tôi dự kiến ban đầu, và có lẽ các hồ bơi NSRunLoop
cuối cùng sẽ dọn dẹp các đối tượng khác nhau NSString
.
LƯU Ý: chủ đề này bây giờ là số 2 Google kết quả cho 'enumerateObjectsUsingBlock autorelease':
Google 'enumerateObjectsUsingBlock+autorelease'
Kết quả đầu tiên khẳng định câu trả lời này. Cảm ơn tất cả.
Wow, thật lạ lùng, tôi không chắc tại sao điều đó không hiệu quả. – jtbandes
Tôi đã thấy mọi người làm một '[[someVariable retain] autorelease]' ở cuối khối để trả lại mọi thứ, nhưng tôi không chắc tại sao điều đó lại tạo nên sự khác biệt nếu như tôi nghi ngờ, một nhóm tự động chạy. Tôi không biết, đó là lý do tại sao tôi hỏi, và có tất cả các loại bài viết về việc sao chép các khối, và truyền đi chúng xung quanh, nhưng không có gì mà tôi có thể tìm thấy trên một thứ đơn giản, như thế này. –
Lỗi/ngoại lệ bạn nhận được là gì? – nacho4d