我有以下函数,导致内存泄漏*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;
}
正如您已经正确指出的那样,所有未显式分配的对象都是"自动释放"的,这意味着一旦它们离开定义它们的函数的范围,它们就会被销毁。
要使对象的有效期超过此时间,例如,通过将其保留为类对象,您可以对其调用"保留"。这种"保留"需要"释放",就像"分配"的对象一样。
通过将对相关对象的引用作为返回值传递,对象的范围将扩展到函数,该函数首先调用了函数......这意味着,对象将在调用函数结束时被销毁,除非到那时它被保留。
nameOfFile 仍然是那个有问题的对象,因为您将 dateString 的地址复制到该变量,有效地从存在中删除了该字符串(因此它将自动发布)。尽量避免此类作业,除非您有理由,否则以避免混淆。
简而言之:如果你有一个函数调用和返回链,请确保沿线的某个地方没有"保留",它没有得到适当的释放,你会没事的。
了解泄漏的最佳方法是使用仪器及其"泄漏"模板。
"泄漏"仪器将显示哪些对象被泄漏,您将能够立即跳转到 ObjectAlloc 仪器以查看对泄漏对象的保留/释放调用。然后,您应该能够找到缺少的版本的位置。
照原样,您的代码看起来不错 wrt 内存管理。但是,此处创建的大多数字符串都是自动释放的,这意味着当外部自动释放池被耗尽时,它们将被有效地释放。在池排空之前,您的对象可能会泄漏。
在典型的应用程序中,主线程具有由 NSApplication/UIApplication 自动安装的自动释放池,但该池仅在应用程序收到事件时才耗尽(请参阅此问题)
在通常的分离线程(使用 NSThread 或 pthread)中,您必须安装自己的池(并定期清空它们)。
GCD 调度队列会安装自己的自动释放池,并不时将其排空。