2012-01-30 84 views
2

我在我的表格中有泄漏,我正在填充数据。UITableView单元内存泄漏

这里是正在发生的事情:

我已经充满了NSDictionaries(联系人信息)的NSMutableArray,我从SQL数据库每次用户将选择一个新的指数函加载,阵列充满了对那些信息联系人。

由于我使用的实例变量数组来保存数据我想,这样的事情每一个新的数据在交换时之前:

if (currentConnections != nil) { 
    [currentConnections release]; 
    currentConnections = nil; 
} 

将有效地摆脱我的旧数据之前,我重新设置。
但是,这是奇怪开始的地方。在我的tableView:cellForRowAtIndexPath:中,我拨打这样的电话:

NSString *firstname = [[currentConnections objectAtIndex:indexPath.row] 
         objectForKey:@"firstname"]; 
UILabel *name = [[UILabel alloc] 
       initWithFrame:CGRectMake(75, 12, 190, 15)]; 
name.font = [UIFont fontWithName:@"Gotham-Medium.ttf" 
          size:12]; 
name.textColor = [UIColor whiteColor]; 
name.backgroundColor = [UIColor clearColor]; 
name.text = firstname; 

其中当前连接是词典数组。我然后添加UILabel作为小区的子视图:

[cell addSubview:name]; 
[name release]; 

从这个行为是这样的:

当运行如(每个交换之前释放当前连接然后将新数据加载到它)该应用程序会因访问错误而崩溃。
当我不发布子视图时,我添加到单元格的应用程序不会崩溃,但我看着恐怖的活字节继续积累在内存分配工具中,直到我切换联系信息的时候,我得到一个内存警告然后崩溃。

在我看来,在单元格和子视图中会出现一些奇怪的内存所有权问题。我确实将单元格指定为可重用的,并在将每个数据加载之前将其指定给autorelease。

任何可能导致此泄漏的想法?

编辑:

这是当前的tableView:的cellForRowAtIndexPath:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 

static NSString *MyIdentifier = @"MyIdentifier"; 
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier]; 

cell.accessoryType = UITableViewCellAccessoryNone; 

if (cell == nil) { 
    NSLog(@"within"); 
    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] autorelease]; 
} 

if (!ALOCATED) { 


cellName = [[ UILabel alloc ] 
       initWithFrame:CGRectMake(75, 12, 190, 15) 
       ]; 
cellName.font = [ UIFont 
      fontWithName:@"Gotham-Medium.ttf" 
      size:12 
      ]; 
cellName.textColor = [ UIColor whiteColor ]; 
cellName.backgroundColor = [ UIColor clearColor ]; 

NSString *firstname = [[ currentConnections 
         objectAtIndex:indexPath.row 
         ] objectForKey:@"firstname" 
         ]; 

firstname = [ firstname stringByAppendingString:@" " ]; 

NSString *lastname = [[ currentConnections 
         objectAtIndex:indexPath.row 
         ] objectForKey:@"lastname" 
         ]; 

UIImage *profPic = [[ currentConnections 
        objectAtIndex:indexPath.row 
        ] objectForKey:@"profilepicture" 
        ]; 
connectionPhoto = [[ UIImageView alloc ] initWithFrame:CGRectMake(10, 8, 56, 56) ]; 
connectionPhoto.image = profPic; 




NSString *fullname = [ firstname stringByAppendingString:lastname ]; 

cellName.text = fullname; 


[ cell addSubview:cellName ]; 



cellTitle = [[ UILabel alloc ] 
       initWithFrame:CGRectMake(75, 31, 260, 13) 
       ]; 
cellTitle.font = [ UIFont 
      fontWithName:@"ArialMT" 
      size:10 
      ]; 
cellTitle.textColor = [ UIColor whiteColor ]; 
cellTitle.backgroundColor = [ UIColor clearColor ]; 
cellTitle.text = [[ currentConnections 
        objectAtIndex:indexPath.row 
        ] objectForKey:@"title" 
       ]; 


[ cell addSubview:cellTitle ]; 
[ cell addSubview:connectionPhoto ]; 
[ profPic release ]; 

    ALOCATED = YES; 

} else { 



    cellTitle.text = [[ currentConnections 
         objectAtIndex:indexPath.row 
         ] objectForKey:@"title" 
         ]; 

    connectionPhoto.image = [[ currentConnections 
                  objectAtIndex:indexPath.row 
                  ] objectForKey:@"profilepicture" 
          ]; 


    NSString *firstname = [[ currentConnections 
          objectAtIndex:indexPath.row 
          ] objectForKey:@"firstname" 
          ]; 

    firstname = [ firstname stringByAppendingString:@" " ]; 

    NSString *lastname = [[ currentConnections 
          objectAtIndex:indexPath.row 
          ] objectForKey:@"lastname" 
          ]; 
    NSString *fullname = [ firstname stringByAppendingString:lastname ]; 

    cellName.text = fullname; 

} 

return cell; 

} 

当我试图创建一个细胞并重新使用它,只有改变每次它的子视图的属性。

编辑

发生了什么事是,我是将子视图细胞对象本身,这是造成泄漏,因为这些没有被释放。只要我开始将视图添加到UITableViewCell成员视图aka cell.contentView,cell.accessoryView等......内存被释放。正如丹尼尔在下面提到的,要么创建一个自定义表格单元格,并将您的视图添加到您的单元格属性,或将您的视图添加到成员uitablecellviews而不是单元格本身。以下为我工作:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 

static NSString *MyIdentifier = @"MyIdentifier"; 
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MyIdentifier]; 

cell.accessoryType = UITableViewCellAccessoryNone; 

if (cell == nil) { 

    cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:MyIdentifier] autorelease]; 
} 




UILabel *cName = [[ UILabel alloc ] 
       initWithFrame:CGRectMake(105, 10, 190, 15) 
       ]; 
cName.font = [ UIFont 
      fontWithName:@"Gotham-Medium.ttf" 
      size:12 
      ]; 
cName.textColor = [ UIColor whiteColor ]; 
cName.backgroundColor = [ UIColor clearColor ]; 

NSString *firstname = [[ currentConnections 
         objectAtIndex:indexPath.row 
         ] objectForKey:@"firstname" 
         ]; 

firstname = [ firstname stringByAppendingString:@" " ]; 

NSString *lastname = [[ currentConnections 
         objectAtIndex:indexPath.row 
         ] objectForKey:@"lastname" 
         ]; 

NSString *fullname = [ firstname stringByAppendingString:lastname ]; 

cName.text = fullname; 

[ cell.contentView addSubview:cName ]; 
[ cName release ]; 



cell.imageView.image = [[ currentConnections 
        objectAtIndex:indexPath.row 
        ] objectForKey:@"profilepicture" 
        ]; 



UILabel *cTitle = [[ UILabel alloc ] 
       initWithFrame:CGRectMake(105, 25, 190, 13) 
       ]; 
cTitle.font = [ UIFont 
      fontWithName:@"ArialMT" 
      size:10 
      ]; 
cTitle.textColor = [ UIColor whiteColor ]; 
cTitle.backgroundColor = [ UIColor clearColor ]; 
cTitle.text = [[ currentConnections 
        objectAtIndex:indexPath.row 
        ] objectForKey:@"title" 
       ]; 


[ cell.contentView addSubview:cTitle ]; 
[ cTitle release ]; 

return cell; 

} 
+2

呃?你如何添加一个NSString作为子视图 – Daniel 2012-01-30 17:58:09

+0

我刚刚编辑它。哎呀是这是一个标签,我添加为子视图 – 2012-01-30 19:01:40

回答

5

如果您正在重用细胞,每次你设置要添加一个UILabel给它的单元格,然后你可以看到很多UILabels都被分配可能会导致你的内存问题...如果你想为单元添加一个标签,当你分配它时,你只需要做一次,然后如果单元格作为一个重用单元格进入,它将已经包含你添加的UILabel,所以你只需要编辑标签文本,而不是添加一个新的UILabel ...这只是从你已发布的猜测,一些更多的代码可能会澄清事情...

问题是显而易见的,你发布的代码,你泄漏的单元格实例变量,也请记住cellForRowAtIndexPath被调用的表中的每一行,所以保持一个实例变量来跟踪添加到单元格的东西将无法正常工作,该var将继续被overwriten,但在你的情况下,你正在泄漏单元格。您正在向UITableViewCell添加单元格,从不释放它们,然后在下一次调用cellForRowAtIndexPath时,单元格var会被覆盖,而前一个单元格会泄漏,因为您没有办法再释放它了...您可以通过释放单元格...

现在你也有使用一个var来跟踪单元格上的标签的问题,请记住,它不是一个单元格被分配重用,它确实是单元格可以显示在屏幕上,一个变种,以便跟踪将无法正常工作是您的问题......为了解决这个问题,我将继承的UITableViewCell有一个标签属性,并必须重新设置标签文本的方法..

希望这有助于

+0

这对我有意义。我想我仍然不明白系统如何处理表格视图单元格。我只尝试分配标签和图像视图,我第一次使用单元格时创建,之后只是更新属性。但是,我的表格只显示其最初的单元格,其余都是空的。你有这种细胞再利用的良好模式的例子吗? – 2012-01-30 20:48:09

+0

发布您的cellforRowAtIndexPath,可能能够看到哪里出错 – Daniel 2012-01-30 20:51:34

+0

我向原始问题添加了其他代码。谢谢。 – 2012-01-30 21:28:10

1
  • 有这么多的接触,你不能加载所有在同一阵列中?
  • 你可以使用NSMutableArray和方法removeAllObjects。
  • 在您的代码:

    [cell addSubview:firstname]; firstname是一个字符串......你不能添加一个NSString作为子视图...我推荐创建一个自定义的UITableviewcell,因为单元格被回收,当你使用一个循环单元格时,在他创建期间添加了所有的子视图。

+0

我做了上面的编辑,我忘了提及我将文本分配给标签,并将其添加为子视图。 removeAllObjects似乎没有摆脱分配的内存。所以现在我正在考虑使用自定义单元格。我仍然不确定为什么采取我的方法会导致额外的记忆永远停留。任何想法? – 2012-01-30 19:46:51