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

pse*_*bos 16 iphone cocoa-touch memory-management objective-c autorelease

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

在阅读了
针对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
Run Code Online (Sandbox Code Playgroud)

这段代码有效吗?

从Apple文本据我所知,从NSString的返回泛函是在范围内有效functionB.我不确定它在functionCviewDidLoad中是否有效.

谢谢!

Jon*_*ess 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];
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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