我是objective-c的新手,我正在努力理解内存管理,以使它变得正确。
在阅读了优秀的
苹果的Memory Management Programming Guide for Cocoa我唯一关心的是当一个自动释放的对象在iphone/ipod应用程序中被释放的时候。我的理解是在run循环的末尾。但是,是什么定义了应用程序中的运行循环呢?
所以我想知道下面这段代码是否正确。假设一个对象
@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.中是否有效
谢谢!
发布于 2010-03-23 16:46:56
是的,您的函数是有效的,并使用正确的Cocoa保留/释放/自动释放/复制约定返回对象。
为了回答您关于运行循环是什么的问题,在应用程序的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时,该对象都会被添加到run循环中的outter池中。当当前事件完成分派后,池将被排空,这些对象最终将被发送释放消息。
最后一句话。可以有多个自动释放池,这些池并不总是在事件循环的末尾。有时,您可能会通过事件循环在一次访问中分配数万个对象。当发生这种情况时,您可以在自己的方法中设置额外的内部自动释放池,以减少自动释放池中的自动释放对象的数量。自动释放池可以堆叠。
发布于 2010-03-23 16:05:28
这段代码没有任何问题。它会像你所期望的那样编译和运行。
从functionA
返回的NSString
对象在返回时仍然有效,因为它正沿着堆栈向下传递给正在跟踪它的下一个人(functionB
)。
https://stackoverflow.com/questions/2498330
复制相似问题