应用程序显示仪器泄漏,这个简单的代码有什么问题?

时间:2011-12-04 16:18:05

标签: iphone objective-c ios ios5 instruments

我很简单地将我的数据导出为CSV文件。但是,当我单击“导出”按钮时,“泄漏仪器”会显示[NSPlaceholderMutableString init]错误。

我在Placeholder的任何地方都没有使用过NSMutableString,那么仪器显示泄漏有什么不对。

这是我的代码:

- (IBAction)btnExportDataPressed:(id)sender
{
    csvString = [[NSMutableString alloc] init];
    csvString = [NSMutableString stringWithFormat:@"No.,Name,Type,MaskPAN,SwipeTime\n"];
    NSString *msg = @"";

    if (self.totalCards.count>0)
    {
        for (int i=0; i<self.totalCards.count; i++)
        {
            self.cardInfo = [self.totalCards objectAtIndex:i];
            [csvString appendString:[NSMutableString stringWithFormat:@"%d,%@ %@,%@,%@,%@\n",i+1,self.cardInfo.firstName,self.cardInfo.lastName,self.cardInfo.type,self.cardInfo.maskedPAN,self.cardInfo.swipeTime]];
        }
        NSLog(@"csvString:%@",csvString);

        NSFileManager *fileManager = [NSFileManager defaultManager];
        NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
        NSString *documentsDirectory = [paths objectAtIndex:0];
        NSString *fileName = [NSString stringWithFormat:@"ORANGE_BOWL_%@",[NSDate date]];

        NSString *fullPath = [documentsDirectory stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.csv",fileName]];
        [fileManager createFileAtPath:fullPath contents:[csvString dataUsingEncoding:NSUTF8StringEncoding] attributes:nil];
        msg = @"Data exported successfully. Connect the device to iTunes to get the records.";
    }
    else
    {
        msg = @"No Data to Export";
    }

    [csvString release];        
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"Discover Orange Bowl," message:msg delegate:self cancelButtonTitle:@"OK" otherButtonTitles:nil, nil];
    [alert show];
    [alert release];
}

以下是来自Instrument

的错误图片

enter image description here

3 个答案:

答案 0 :(得分:2)

代码顶部有内存泄漏:

csvString = [[NSMutableString alloc] init];
csvString = [NSMutableString stringWithFormat:@"No.,Name,Type,MaskPAN,SwipeTime\n"];

因此,您为可变字符串(第1行)分配内存,该字符串将保留计数加1,然后在第2行中丢失指针引用,因为您为指针指定了另一个字符串。这肯定会泄漏内存;不确定你的其他代码是否做了其他不好的事情。

所以删除第一行 - 它没用,只会导致内存泄漏。

此外,您的[csvString release]行看起来有误,因为当您上次向csvstring分配内容时,您使用的[NSMutableString stringWithFormat]不会增加保留计数(因此您不应该减少它)使用release)。因此,请尝试删除显示[csvString release];

的行

Leaks工具可以显示对您实际未使用的对象的略微莫名其妙的引用;这是由您使用(和泄漏)的对象在内部使用这些对象引起的。

答案 1 :(得分:0)

更改

csvString = [NSMutableString stringWithFormat:@"No.,Name,Type,MaskPAN,SwipeTime\n"];

[csvString appendFormat:@"No.,Name,Type,MaskPAN,SwipeTime\n"];

答案 2 :(得分:0)

如果您使用alloc初始化<{1}},则不应在init上致电releasecsvStringstringWithFormat:

initstringWithFormat:方法记录在Creating and Initializing Strings下的NSString文档中。你应该选择其中一个,而不是两个。在这种情况下,您可能只想使用stringWithFormat:

您应该阅读Objective-C memory management,但这里的一般准则是:如果您用于创建对象的方法以init开头,那么您使用alloc和{{1 }}。如果该方法不以release开头,则您不要使用initalloc