【问题标题】:iPhone memory leak because of stringWithUTF8String由于 stringWithUTF8String 导致 iPhone 内存泄漏
【发布时间】:2010-09-06 06:36:44
【问题描述】:

我有以下代码,它显示了带有 stringWithUTF8String 的语句附近最喜欢的对象的内存泄漏。

我已在属性中声明收藏夹

-(NSMutableArray *) readFavoritesFromDatabase 
{
 // Check if database is present
 [self setDatabaseNameAndPath];
 [self checkAndCreateDatabase];

 // Setup the database object
 sqlite3 *database;

 //Initialize favorites array
 if (favorites == nil) 
 {
  [favorites release];
  favorites = [[NSMutableArray alloc] init];
 }
 else 
 {
  favorites = nil;
  [favorites removeAllObjects];
 }


 // Open the database from the users file system
 if(sqlite3_open([self.dataBasePath UTF8String], &database) == SQLITE_OK) 
 {
  // Setup the SQL Statement and compile it for faster access
  const char *sqlStatement = "select * from Favorites";
  sqlite3_stmt *compiledStatement;

  if(sqlite3_prepare_v2(database, sqlStatement, -1, &compiledStatement, NULL) == SQLITE_OK) 
  {

   // Loop through the results and add them to the favorites array
   while(sqlite3_step(compiledStatement) == SQLITE_ROW) 
   {
    // Create Favorite object and add it to the Favorite array
    Favorite *favorite = [[[Favorite alloc] init] autorelease];

    favorite.cameraID = [NSString stringWithUTF8String:(const char*)sqlite3_column_text(compiledStatement, 0)];
    favorite.cameraName = [NSString stringWithUTF8String:(const char*)sqlite3_column_text(compiledStatement, 1)];
    favorite.cameraLink = [NSString stringWithUTF8String:(const char*)sqlite3_column_text(compiledStatement, 2)];

    [self.favorites addObject:favorite];
    //[favorite.cameraID release];
//    [favorite.cameraName release];
//    [favorite.cameraLink release];
   }

   // If favorite cameras exists in database, then sort the Favorites array 
   if([self.favorites count]>0)
   {

    NSSortDescriptor *favoritesNameSorter = [[NSSortDescriptor alloc] initWithKey:@"cameraName" ascending:YES];
    [self.favorites sortUsingDescriptors:[NSArray arrayWithObject:favoritesNameSorter]];
    [favoritesNameSorter release];
   }
  }

  // Release the compiled statement from memory
  sqlite3_finalize(compiledStatement);
 }

 // Close the database
 if(database !=nil)
 {
  sqlite3_close(database);
  return self.favorites;
 }
 else 
 {
  return nil;
 }
}

请告诉我如何解决这个内存泄漏问题 提前致谢。

【问题讨论】:

标签: iphone memory memory-leaks


【解决方案1】:

使用这种安全的方法:

Favorite *tempFavorite = [[Favorite alloc] init];
self.favorite = tempFavorite;
[tempFavorite release];

通常,在您最喜欢的 dealloc 函数中,您应该在调用 super dealloc 函数之前删除所有对象并清理必要的内容。

使用这种方式,您无需担心 favourite 是否为 nil,因为 Objective-c 允许调用 nil 对象的方法

问候

梅厄阿萨亚格

【讨论】:

  • 这里最喜欢的是一个局部变量。所以我认为没有理由这样做。请详细说明。
【解决方案2】:

不确定stringWithUTF8String 泄漏,但这是个问题:

favorites = nil;
[favorites removeAllObjects];

你泄露了favorites 中的内容,然后告诉nil 对象删除所有对象——它是nil,根据定义它没有。然后稍后您尝试向其中添加对象;这也行不通。

【讨论】:

  • 我之前只保留了 [favorites removeAllObjects] ,但这并没有消除内存泄漏。此代码工作正常
  • favorites 的旧内容分配给nil 后会发生什么情况?
【解决方案3】:

我没有在您的 stringWithUTF8String 中看到任何泄漏,该代码运行良好。但是,查看整个方法,我发现某些东西会造成内存问题,例如泄漏或崩溃。如果您已经为收藏夹声明了一个属性,那么您应该在这里使用self.favorites

 //Initialize favorites array
 if (favorites == nil) 
 {
  [favorites release];
  favorites = [[NSMutableArray alloc] init];
 }
 else 
 {
  favorites = nil;
  [favorites removeAllObjects];
 }

变成:

 //Initialize favorites array
 if (self.favorites == nil) 
 {
  self.favorites = [[NSMutableArray alloc] init];
 }
 else 
 {
  self.favorites = nil;
 }

它会在内存管理中帮助你很多事情,比如在你的 else 条件下,你将变量设置为 nil 但不释放它,在第一个条件下,你释放一个 nil 对象?

【讨论】:

  • 我认为我的第一个答案不够清楚,也没有真正直接回答这个问题。希望编辑后的版本能对提问者有所帮助
  • 如果favorites 属性被定义为(retain),你不应该使用它。
  • 嗯?为什么不呢,我认为如果属性是(保留)你应该使用它,因为它会释放并设置为新对象,然后为你保留,对吧?
  • 我已将assign用于收藏夹而不是保留
猜你喜欢
  • 1970-01-01
  • 2011-05-05
  • 2016-02-15
  • 2016-07-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-03-03
  • 2013-07-23
相关资源
最近更新 更多