0

我有以下功能,这会导致*timeString内存泄漏。我对Objective-C(和内存管理)相当陌生,但我读到您只需要首先release使用您的对象alloc。因为 I 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;
}
4

2 回答 2

1

正如您已经正确指出的那样,所有未显式分配的对象都是按照定义“自动释放”的,这意味着一旦它们离开定义它们的函数范围,它们就会被销毁。

要使对象的有效期更长,例如,通过将其作为类对象保留,您可以在其上调用“保留”。这个“保留”需要“释放”,就像一个“分配”的对象。

通过将相关对象的引用作为返回值传递,对象的范围扩展到函数,该函数首先调用该函数......这意味着,该对象将在调用函数结束时被销毁, 除非它在那时被保留。

nameOfFile 仍然是那个有问题的对象,因为您将 dateString 的地址复制到了该变量,有效地从存在中删除了该字符串(因此它将自动释放)。尽量避免这样的分配,除非你有理由这样做,以避免混淆。

简而言之:如果您有一系列函数调用和返回,请确保沿线某处没有“保留”,它没有被适当地释放,你会没事的。

于 2012-08-14T18:10:00.577 回答
0

了解泄漏的最佳选择是使用 Instruments 及其“泄漏”模板。

“泄漏”工具将向您显示哪些对象被泄漏,您将能够立即跳转到 ObjectAlloc 工具以查看对泄漏对象的保留/释放调用。然后,您应该能够找到丢失的版本在哪里。

照原样,您的代码在内存管理方面看起来不错。然而,这里创建的大多数字符串都是自动释放的,这意味着当外部自动释放池被耗尽时,它们将被有效释放。在池被耗尽之前,您的对象可能会出现泄漏。

在典型的应用程序中,主线程有一个由 NSApplication/UIApplication 自动安装的自动释放池,但只有当应用程序接收到事件时,池才会被耗尽(参见这个问题

在通常的分离线程(使用 NSThread 或 pthread)中,您必须安装自己的池(并定期排空它们)。

GCD 调度队列会安装自己的自动释放池并时不时地耗尽它们。

于 2012-08-14T18:02:20.933 回答