如果有人能帮我解决漏水问题,我将不胜感激。泄漏发生在:aImage,aCategory,aDescription,category和categories。我以dealloc发布它们,但显然这还不够:
-(void) readListFromDatabase:(char *) sqlStatement {
// Setup some globals
databaseName = @"mydatabase.sql";
// Get the path to the documents directory and append the databaseName
NSArray *documentPaths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *documentsDir = [documentPaths objectAtIndex:0];
databasePath = [documentsDir stringByAppendingPathComponent:databaseName];
// Setup the database object
sqlite3 *database;
// Init the categories Array
categories = [[NSMutableArray alloc] init];
// Open the database from the users filessytem
if(sqlite3_open([databasePath UTF8String], &database) == SQLITE_OK) {
// Setup the SQL Statement and compile it for faster access
sqlite3_stmt *compiledStatement;
if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) {
// Loop through the results and add them to the feeds array
while(sqlite3_step(compiledStatement) == SQLITE_ROW) {
// Read the data from the result row
aImage = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 0)];
aCategory = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 1)];
aDescription = [NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 2)];
// Create a new category object with the data from the database
category=[[Category alloc] initWithName:aImage category_name:aCategory description_text:aDescription];
// Add the category object to the categories Array
[categories addObject:category];
[category release];
}
}
// Release the compiled statement from memory
sqlite3_finalize(compiledStatement);
}
sqlite3_close(database);
}
- (void)dealloc {
[databaseName release];
[databasePath release];
[categories release];
[aImage release];
[aCategory release];
[aDescription release];
[category release];
[super dealloc];
}
答案 0 :(得分:2)
如果多次调用该方法,则字符串将泄漏,因为您需要释放以前的值。你也在dealloc中过度发布字符串,因为你从未保留它们。你应该写这样的作业:
[aImage release];
aImage = [[NSString stringWithUTF8String:(char *)sqlite3_column_text(compiledStatement, 0)] retain];
这些字符串可能泄漏的唯一另一种方式是,如果从线程调用此方法并且您没有创建自动释放池。
如果从新线程调用该方法,则需要一个自动释放池:
- (void)myThreadFunction {
NSAutoReleasePool *pool = [[NSAutoReleasePool alloc] init];
try {
// ...
[self readListFromDatabase:whatever];
// ...
} @finally {
[pool release];
}
}
答案 1 :(得分:1)
您发布的方法是否在同一个对象上被多次调用?如果是,则第一次调用的类别将泄漏,因为每次调用readListFromDatabase:时都会覆盖它。尝试:
// Init the categories Array
[categories release];
categories = [[NSMutableArray alloc] init];
答案 2 :(得分:0)
为什么当我在循环中包含[aImage autorelease]时应用程序终止(如果[aImage release]它也会终止)?
答案 3 :(得分:0)
有点晚了,但我正在更新一个旧项目并遇到了类似的问题。 我有一个错误命名的便利方法!
- (NSString *)initStringFromPosition:(int)index {
char *str = (char *)sqlite3_column_text(init_statement, index);
return (str) ? [NSString stringWithUTF8String:str] : @"";
}
分析说我有内存泄漏,但是简单地重命名为
- (NSString *)stringFromPosition:(int)index {
解决了问题