为什么我不能发布这个对象? iPhone dev / UITableView(Objective C)

时间:2010-06-16 15:33:22

标签: objective-c uitableview memory-management

我正在学习Obj-C,但偶尔也会有困难时间围绕着一些内存管理工作。我正在使用带有UITableView的自定义单元格,并实现了cellForRowAtIndexPath方法,我不小心在最后释放了单元格。这显然会导致问题,因为当弹出tableView时,单元格也会被释放。由于释放细胞两次导致崩溃 - 没有概率,理解。

然而,当我继续工作时,我混合了标准和自定义单元格,所以我的方法变得有点复杂。我的第一次尝试是下面的,它引起了与上述场景相同的问题。这是我有点困惑的地方 - 因为我没有发布“cell”,为什么我在将单元格设置为其值后才能发布“customCell”?

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

     UITableViewCell *cell;

     //CATEGORY_SECTION is a constant defined elsewhere
     if (indexPath.section == CATEGORY_SECTION) {
          cell = [tableView dequeueReusableCellWithIdentifier:@"StandardCellIdentifier"];
          if (cell == nil) {
               cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"StandardCellIdentifier"] autorelease];
               cell.accessoryType = UITableViewCellAccessoryCheckmark;
          }
          cell.labelText.text = myModelObject.name;

     } else {

          cell = [tableView dequeueReusableCellWithIdentifier:@"CustomCellIdentifier"];
          MyCustomCellClass *customCell;
          if (cell == nil) {
               UIViewController *helperController = [[UIViewController alloc] initWithNibName:@"MyCustomCell" bundle:nil];
               customCell = (MyCustomCellClass *)[helperController view];


               [helperController release];
          }

     customCell.myCustomLabel.text = myModelObject.description;
     cell = customCell;
     [customCell release];
     }

     return cell;
}

据我所知,当我设置cell = customCell时,我将customCell的内存地址而不是实际对象分配给单元格...所以当我发布customCell时它还实际上释放了单元格?我如何实际复制customCell以便我可以发布它?或者我不必释放它(即使我分配了它) - 它似乎等待发生内存泄漏,你会如何接近它?

记录中,这是我用来避免此问题的修订代码。这个问题不仅仅是找到解决方案(因为我有,下面),而是了解幕后发生的事情。谢谢你的指导!

我的工作方法:

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

     //CATEGORY_SECTION is a constant defined elsewhere
     if (indexPath.section == CATEGORY_SECTION) {
          UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"StandardCellIdentifier"];
          if (cell == nil) {
               cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"StandardCellIdentifier"] autorelease];
               cell.accessoryType = UITableViewCellAccessoryCheckmark;
          }
          cell.labelText.text = myModelObject.name;

          return cell;

     } else {

          MyCustomCell *customCell = (MyCustomCell *)[tableView dequeueReusableCellWithIdentifier:@"CustomCellIdentifier"];

          if (customCell == nil) {
               UIViewController *helperController = [[UIViewController alloc] initWithNibName:@"MyCustomCell" bundle:nil];
               customCell = (MyCustomCell *)[helperController view];
               [helperController release];
          }

          customCell.myCustomLabel.text = myModelObject.description;

          return customCell;
     }
}

2 个答案:

答案 0 :(得分:2)

是的,你正在释放两个变量所指向的相同内存。例如,如果您要设置类属性,则该属性可能会标记为retain。如果属性具有retain,则意味着它想要“拥有”该对象。然后你可以发布它。

在您的情况下,您的单元格变量不拥有内存,因此您无法释放它。

答案 1 :(得分:0)

请阅读Apple memory management rules。在你的第一个例子中

a)customCell是一个ivar

b)您在转录代码时犯了一个错误,而customCell是从[helperController视图]获得的。

无论哪种方式,您都没有使用new,alloc或包含“Copy”的方法获取customCell。你也没有保留customCell。因此,您不得释放它(在您的方法范围内)。