什么时候释放自动释放的对象?

时间:2010-03-23 08:02:22

标签: objective-c iphone cocoa-touch memory-management autorelease

我是objective-c的新手,我正在努力理解内存管理以使其正确。

阅读后的优秀作品 苹果Memory Management Programming Guide for Cocoa我唯一担心的是什么时候 实际上,在iphone / ipod应用程序中发布了一个自动释放的对象。我的理解是在运行循环结束时。但是什么定义了应用程序中的运行循环?

所以我想知道下面的代码是否正确。假设一个对象

@implementation Test

- (NSString *) functionA {
    NSString *stringA;
    stringA = [[[NSString alloc] initWithString:@"Hello"] autorelease]
    return stringA;
}

- (NSString *) functionB {
    NSString *stringB;
    stringB = [self functionA];
    return stringB;
}

- (NSString *) functionC {
    NSString *stringC;
    stringC = [self functionB];
    return stringC;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    NSString* p = [self functionC];
    NSLog(@"string is %@",p);
}

@end

这段代码有效吗?

从苹果文本中我了解到,从 functionA 返回的NSString在 functionB 的范围内有效。我不确定它在 functionC viewDidLoad 中是否有效。

谢谢!

2 个答案:

答案 0 :(得分:17)

是的,您的函数是有效的,并使用正确的Cocoa约定返回对象以进行retain / release / autorelease / copy。

要回答关于runloop是什么的问题,在应用程序的main()函数中,它会调用UIApplicationMain()。你可以想象UIApplicationMain看起来像这样:

void int UIApplicationMain (int argc, char *argv[], NSString *principalClassName, NSString *delegateClassName) {
    UIApplication *app = /* create app using principalClassName */;
    [app setDelegate:/* create delegate using delegateClassName */];
    while (![app shouldTerminate]) {
        NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
        event = [app getNextEvent];
        [app dispatchEvent:event];
        [pool drain];
    }
}

while循环类似于UIKit实际执行的操作,并且每次循环都是通过runloop跳转,其中函数getNextEvent阻塞等待某个事件发生。所有方法通常都是从dispatchEvent:中调用的。您可以尝试在其中一个方法中设置断点,例如IBAction,并在顶部查看调试器调用堆栈,以查看处理事件和runloop的UIKit方法的名称。由于每个方法都是在while循环中调用的,因此每次在对象上调用autorelease时,该对象都会在运行循环中添加到该outter池中。当调度完当前事件后,池就会耗尽,最后会发送这些对象的释放消息。

最后一点。可以有多个自动释放池,它们并不总是在事件循环的末尾。有时您可以通过事件循环在一次旅行中分配数万个对象。发生这种情况时,您可以在自己的方法中设置其他内部自动释放池,以保持自动释放池中自动释放对象的数量。自动释放池可以堆叠。

答案 1 :(得分:0)

该代码没有任何问题。它将按预期编译和运行。

NSString返回的functionA对象在返回时仍然有效,因为它正在向下传递给下一个正在跟踪它的人(functionB)。