内存从我没有分配的对象泄漏



我有以下函数,导致内存泄漏*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 调度队列会安装自己的自动释放池,并不时将其排空。

最新更新