我正在学习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;
}
}
答案 0 :(得分:2)
是的,你正在释放两个变量所指向的相同内存。例如,如果您要设置类属性,则该属性可能会标记为retain
。如果属性具有retain
,则意味着它想要“拥有”该对象。然后你可以发布它。
在您的情况下,您的单元格变量不拥有内存,因此您无法释放它。
答案 1 :(得分:0)
请阅读Apple memory management rules。在你的第一个例子中
a)customCell是一个ivar
或
b)您在转录代码时犯了一个错误,而customCell是从[helperController视图]获得的。
无论哪种方式,您都没有使用new,alloc或包含“Copy”的方法获取customCell。你也没有保留customCell。因此,您不得释放它(在您的方法范围内)。