我是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 中是否有效。
谢谢!
答案 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
)。