在我的应用程序中,此方法显示内存泄漏如何删除泄漏?
-(void)getOneQuestion:(int)flashcardId categoryID:(int)categoryId
{
flashCardText = [[NSString alloc] init];
flashCardAnswer=[[NSString alloc] init];
//NSLog(@"%s %d %s", __FILE__, __LINE__, __PRETTY_FUNCTION__, __FUNCTION__);
sqlite3 *MyDatabase;
sqlite3_stmt *CompiledStatement=nil;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *MyDatabasePath = [documentsDirectory stringByAppendingString:@"/flashCardDatabase.sqlite"];
if(sqlite3_open([MyDatabasePath UTF8String],&MyDatabase) == SQLITE_OK)
{
sqlite3_prepare_v2(MyDatabase, "select flashCardText,flashCardAnswer,flashCardTotalOption from flashcardquestionInfo where flashCardId=? and categoryId=?", -1, &CompiledStatement, NULL);
sqlite3_bind_int(CompiledStatement, 1, flashcardId);
sqlite3_bind_int(CompiledStatement, 2, categoryId);
while(sqlite3_step(CompiledStatement) == SQLITE_ROW)
{
self.flashCardText = [NSString stringWithUTF8String:(char *)sqlite3_column_text(CompiledStatement,0)];
self.flashCardAnswer= [NSString stringWithUTF8String:(char *)sqlite3_column_text(CompiledStatement,1)];
flashCardTotalOption=[[NSNumber numberWithInt:sqlite3_column_int(CompiledStatement,2)] intValue];
}
sqlite3_reset(CompiledStatement);
sqlite3_finalize(CompiledStatement);
sqlite3_close(MyDatabase);
}
}
这种方法也显示泄漏.....这种方法有什么问题?
-(void)getMultipleChoiceAnswer:(int)flashCardId
{
if(optionsList!=nil)
[optionsList removeAllObjects];
else
optionsList = [[NSMutableArray alloc] init];
sqlite3 *MyDatabase;
sqlite3_stmt *CompiledStatement=nil;
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask,YES);
NSString *documentsDirectory = [paths objectAtIndex:0];
NSString *MyDatabasePath = [documentsDirectory stringByAppendingString:@"/flashCardDatabase.sqlite"];
if(sqlite3_open([MyDatabasePath UTF8String],&MyDatabase) == SQLITE_OK)
{
sqlite3_prepare_v2(MyDatabase,"select OptionText from flashCardMultipleAnswer where flashCardId=?", -1, &CompiledStatement, NULL);
sqlite3_bind_int(CompiledStatement, 1, flashCardId);
while(sqlite3_step(CompiledStatement) == SQLITE_ROW)
{
[optionsList addObject:[NSString stringWithUTF8String:(char *)sqlite3_column_text(CompiledStatement,0)]];
}
sqlite3_reset(CompiledStatement);
sqlite3_finalize(CompiledStatement);
sqlite3_close(MyDatabase);
}
}
alt text http://www.freeimagehosting.net/uploads/5b8120982c.png
答案 0 :(得分:4)
您实际上并未使用在函数顶部初始化的对象:
flashCardText = [[NSString alloc] init];
flashCardAnswer=[[NSString alloc] init];
在您稍后将这些对象替换为其他对象时
self.flashCardText = [NSString stringWithUTF8String:(char *)sqlite3_column_text(CompiledStatement,0)];
self.flashCardAnswer= [NSString stringWithUTF8String:(char *)sqlite3_column_text(CompiledStatement,1)];
所以那些似乎是泄漏的物体。
答案 1 :(得分:2)
[[NSString alloc] init]完全没有意义。除了更多的工作之外,它将返回完全相同的@“”。它不太可能泄漏,因为系统几乎肯定会返回一个固定的常量空字符串,在init例程中释放[NSString alloc]。但这是毫无意义,毫无用处和糟糕的代码。
除此之外,您的代码看起来还不错。第二种方法可能被认为是“泄漏”了optionsList,只是因为它创建它并且它永远不会被释放,但它只创建一次所以应该没问题。
尝试运行程序并进行泄漏检测,然后打破调试器并使用
po 0x4b2720(替换为泄漏对象的地址)
查看实际泄漏的字符串。
请记住,泄漏可能会产生误报,尤其是在缓存任何内容的情况下。
答案 2 :(得分:1)
[[NSString alloc] init];
是一个无用的短语。删除两个第一行将消除泄漏。
编辑:请注意,除非保留自动释放池,否则一旦自动释放池耗尽,从数据库中提取的两个字符串将会消失。
Redit:关于第二种方法;我看不出任何明显的泄漏。 NSCFStrings创建了很多,并经常坚持下去。这并不意味着他们实际上是泄密。从我所看到的,该方法中的所有内容都是自动释放或持久的。
答案 3 :(得分:1)
-1/2
@""
相当于[[[NSString alloc] init] autorelease];
[[NSString alloc] init]
会泄漏。
请记住规则:init/retain
应由autorelease/release
平衡。