我很简单地将我的数据导出为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
的错误图片
答案 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
上致电release
,csvString
和stringWithFormat:
init
和stringWithFormat:
方法记录在Creating and Initializing Strings下的NSString文档中。你应该选择其中一个,而不是两个。在这种情况下,您可能只想使用stringWithFormat:
。
您应该阅读Objective-C memory management,但这里的一般准则是:如果您用于创建对象的方法以init
开头,那么您使用alloc
和{{1 }}。如果该方法不以release
开头,则您不要使用init
和alloc
。