16

我是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

此代码有效吗?

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

谢谢!

4

2 回答 2

18

是的,您的函数是有效的,并且使用正确的 Cocoa 约定来返回对象,用于保留/释放/自动释放/复制。

要回答关于 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 实际在做的事情,每次通过 while 循环就像通过 runloop 一样,函数 getNextEvent 阻塞等待某个事件发生。您的所有方法通常都是从 dispatchEvent: 之类的内部调用的。您可以尝试在您的一个方法中设置断点,例如 IBAction,然后在顶部的调试器调用堆栈中查看处理事件和运行循环的 UIKit 方法的名称。由于您的每个方法都是从该 while 循环中调用的,因此每次对对象调用 autorelease 时,该对象都会添加到运行循环中的该外部池中。当当前事件完成分发时,池被清空,这些对象最终被发送释放消息。

最后一点。可以有不止一个自动释放池,它们并不总是在事件循环的末尾。有时,您可能会在整个事件循环中一次分配数万个对象。发生这种情况时,您可以在自己的方法中设置额外的内部自动释放池,以减少自动释放池中自动释放对象的数量。自动释放池可以堆叠。

于 2010-03-23T08:46:56.097 回答
0

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

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

于 2010-03-23T08:05:27.750 回答