2009-08-24 21 views
1

在我的应用程序中,此方法显示内存泄漏我如何消除泄漏?如何清除NSString相关的内存泄漏?

-(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

回答

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)]; 

所以这些似乎是泄漏的对象。

+0

我已删除了这两条线,但仍表现出leak..i正在增加从仪器 – 2009-08-24 10:31:18

+0

我使用flashcardtext显示在标签上的文字图片... 但我在使用3-4在flashcardanswer同一类倍...但显示在另一课的文字...如果我从flashcardanswer应用程序中删除自己。会崩溃 – 2009-08-24 11:01:48

+0

他们不会泄漏的属性将(大概)发布flashCardText和flashCardAnswer的(毫无意义)的初始值。 – 2009-08-24 12:47:54

1

[[NSString alloc] init];是一个无用的短语。去掉两条第一条线可以消除泄漏。

编辑:也请注意,随着autoreleasepool排出从数据库中拉两个字符串会尽快消失,除非它们被保留。

Redit:关于第二种方法;我看不到任何明显的泄漏。 NSCFStrings创建了很多,并且经常停留。这并不意味着他们实际上是泄漏。从我所看到的情况来看,该方法中的所有内容都是自动释放或持久化的。

+0

好点的有关自动释放,我没有拿起在那。正好说明它可能过于注重的是有人问:-) – 2009-08-24 09:35:54

+0

所以我应该创造这样 @property头文件属性的问题(非原子,保留)的NSString * flashCardText;或者像这样 @property(nonatomic,copy)NSString * flashCardText; – 2009-08-24 10:03:46

+0

'@property(nonatomic,copy)'通常被认为是字符串的最佳选择,据我记得。 – 2009-08-24 10:06:40

2

[[的NSString的alloc] INIT]是完全没有意义的。它将返回完全相同的@“”,除了更多的工作。它不可能泄漏,因为系统几乎肯定会返回一个固定的常量空字符串,释放init例程中的[NSString alloc]。但它是毫无意义的,无用的和糟糕的代码。

除此之外,你的代码看起来不错。第二种方法可能被认为是“泄漏”optionsList,仅仅是因为它创建它,它永远不会被释放,但它只创建一次,所以它应该没问题。

尝试运行您的程序,做检漏,然后在调试器打破,并使用

PO 0x4b2720(与泄漏对象的地址替换)

,看看有什么字符串实际上泄漏。

记住,泄漏可能产生假阳性,尤其是如果有什么缓存。

+0

+1。 – Abizern 2009-08-24 15:40:14

+0

这不起作用po 0x4b2720(用泄露对象的地址替换)gdb不会打印任何内容... – 2009-08-25 08:59:39

1

-1/2

@""相当于[[[NSString alloc] init] autorelease]; [[NSString alloc] init]会泄漏。

记住的规则:init/retain应该由autorelease/release平衡。