内存管理和performSelectorInBackground:

时间:2009-05-16 20:18:02

标签: objective-c iphone cocoa-touch

哪个是对的?这样:

NSArray* foo = [[NSArray alloc] initWithObjects:@"a", @"b", nil];
[bar performSelectorInBackground:@selector(baz:) withObject:foo];

- (void)baz:(NSArray*)foo {
    ...
    [foo release];
}

或者:

NSArray* foo = [[[NSArray alloc] initWithObjects:@"a", @"b", nil] autorelease];
[bar performSelectorInBackground:@selector(baz:) withObject:foo];

- (void)baz:(NSArray*)foo {
    NSAutoreleasePool* pool = [[NSAutoreleasePool alloc] init];
    ...
    [pool release];
}

我知道第一个有效,但Clang抱怨它,所以我想知道是否有更好的模式可供使用。

我会“尝试”第二个,但是有了自动释放,谁知道EXC_BAD_ACCESS的缺席是否意味着你做得对,或者你是否幸运...

2 个答案:

答案 0 :(得分:24)

首先是错的。

performSelectorInBackground:withObject:保留bar和foo,直到执行任务。因此,您应该在创建它时自动释放foo并让performSelectorInBackground:withObject处理其余的事情。见documentation

后者是正确的,因为您在创建时自动释放foo。您在baz中创建的自动释放池与foo的内存管理的正确性无关。自动释放的对象需要自动释放的对象里面的池分配和baz中的释放,它根本不会触及foo的保留计数。

答案 1 :(得分:2)

现在正确的做法是:

NSArray* foo = [[[NSArray alloc] initWithObjects:@"a", @"b", nil] autorelease];
[bar performSelectorInBackground:@selector(baz:) withObject:foo];

- (void)baz:(NSArray*)foo {
    @autoreleasepool {
        ...
    }
}