我有以下功能,导致*timeString
内存泄漏。我对Objective-C(和内存管理)还不熟悉,但我读到你只需要release
个alloc
对象。因为我alloc
*formatter
,然后将其设置为*timeString
,这是否意味着我现在也必须释放*timeString
?
以下是代码:
-(NSString *)getDate{
NSLog(@"getDate");
NSDateFormatter *formatter;
NSString *timeString;
formatter = [[NSDateFormatter alloc] init];
[formatter setDateFormat:@"yyyy-MM-dd"];
timeString = [formatter stringFromDate:[NSDate date]];
[formatter release];
return timeString;
}
编辑:这是调用getDate
函数的地方:
-(NSString *)getFileName{
//nameofXMLFile = page_##
NSString *nameOfFile = [NSString stringWithString:pageTitle];
//nameOfXMLFile = page_##.DataCheckSheet.xml
nameOfFile = [nameOfFile stringByAppendingString: @".DataCheckSheet.xml"];
NSString *dateString = [self getDate];
dateString = [dateString stringByAppendingString: @"_"];
NSLog(@"datestring: %@", dateString);
dateString = [dateString stringByAppendingString:nameOfFile];
NSLog(@"datestring with append: %@", dateString);
//nameOfXMLFile = yyyy-MM-dd_page_##.DataCheckSheet.xml
nameOfFile = dateString;
return nameOfFile;
}
答案 0 :(得分:1)
正如您已经正确指出的那样,所有未明确分配的对象都是按照“自动释放”的定义,这意味着一旦它们离开定义它们的函数的范围,它们就会被销毁。
要保持对象的有效时间长于此值,例如,通过将其保留为类对象,可以在其上调用“retain”。 这种“保留”需要“释放”,就像“分配”对象一样。
通过将引用传递给相关对象作为返回值,对象的范围扩展到函数,该函数首先调用函数...这意味着对象将在末尾被销毁。调用函数,除非它被保留。
nameOfFile仍然是那个有问题的对象,因为你将dateString的地址复制到该变量,有效地擦除了该字符串(因此它将被自动释放)。 除非你有理由,否则尽量避免这样的任务,以避免混淆。
简而言之:如果你有一系列的函数调用和返回,请确保在该行的某个地方没有“保留”,这不会得到适当的释放,你会没事的。< / p>
答案 1 :(得分:0)
了解泄漏的最佳方法是使用Instruments及其“泄漏”模板。
“泄漏”仪器将显示哪些物体泄漏,您将能够立即跳转到ObjectAlloc仪器,以查看保留/释放对泄漏物体的调用。然后,您应该能够找到缺失的版本。
按原样,您的代码在内存管理方面看起来很好。但是,这里创建的大多数字符串都是自动释放的,这意味着当外部自动释放池耗尽时,它们将被有效释放。在池耗尽之前,您的物体可能会泄漏。
在典型的应用程序中,主线程有一个由NSApplication / UIApplication自动安装的自动释放池,但只有在应用程序收到事件时才会耗尽池(参见this question)
在通常的分离线程中(使用NSThread或pthread),您必须安装自己的池(并定期排空它们)。
GCD调度队列会安装自己的自动释放池并不时将其耗尽。