如果cell == nil,uitableview安全删除?

时间:2012-09-11 11:54:16

标签: objective-c ios uitableview

我正在写一个图像编辑工具。我有一个显示文档文件夹内容的UITableview。这一切都按预期工作。我遇到的问题是添加新文件或从文档文件夹中删除文件。

创建或删除文件时,我在调用重新加载数据之前调用refreshFiles,使用检查if(cell == nil)导致基于文件数组的增加/减少的长度创建/删除单元格。

最后UITableViewCell然后将数组最后位置的文件名作为该字段的名称。但是,新文件名可以位于数组中的任何位置。 为了确保显示正确的内容,我删除了if(cell==nil)检查,然后每次调用时重绘所有单元格。

-(void)refreshFiles {

NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
NSString *pathList = [paths objectAtIndex:0];
NSArray *fileListing = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:pathList error:nil];
NSPredicate *filter = [NSPredicate predicateWithFormat:@"self ENDSWITH '.png'"];
self.fileList = [fileListing filteredArrayUsingPredicate:filter];
[self.fileview reloadData]

}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = @"Cell";

UITableViewCel *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];

  // if (cell == nil) { 
    cell = [[[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault    reuseIdentifier:CellIdentifier]autorelease];

objectAtIndex:indexPath.row],self.fileList.count,indexPath.row);
    cell.textLabel.text = [self.fileList objectAtIndex:indexPath.row];

  //   }

return cell;
}

然而,这是一种有效的工作方式吗?这会导致我的性能问题吗?

4 个答案:

答案 0 :(得分:2)

所以现在你总是创建一个新的UITableViewCell而不是重用可能排队的UITableViewCell。

检查cell == nil是否有可以重新使用的单元格。如果不是nil,则必须重新创建它。

就像我现在说的那样,你没有使用Apple为UITableView创建的智能排队机制。它是为了表现所以,如果我是你,我仍然会有这个检查。

答案 1 :(得分:1)

原始代码中存在一个简单错误:只有在分配了新单元格时才设置单元格文本,而不是在重复使用单元格时。正确的顺序是:

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) { 
    cell = [[[CustomCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
cell.textLabel.text = [self.fileList objectAtIndex:indexPath.row];

答案 2 :(得分:0)

这绝对安全,您可以省略dequeueReusableCellWithIdentifier调用并创建没有重用标识符的单元格。

当然这意味着你不会重复使用单元格,但我发现如果单元格没有大量使用内存但需要大量的UI表示逻辑,那么它将是一种有用的方法。在这种情况下,我可以负责单元缓存并手动执行,这会与reuseIdentifier逻辑冲突。

我遇到这种情况的方法是创建抽象的Section类,至少存储标题id,名称,节标题视图和Row对象数组,至少存储单元格视图和相关的单元格信息。

作为奖励,您可以进行超级简单的部分管理,例如:你可以实现平滑的部分动画,比如折叠和展开。

然而,对于最简单的表,我总是遵循reuseIdentifier方法,因为实现起来要快得多。

答案 3 :(得分:0)

正如彼得的回答所暗示的那样,我认为如果cell==nil逻辑,你可能会对目的感到困惑。你想把它留在那里。如果您已从self.fileList删除了商品,假设您的tableView:numberOfRowsInSection:只返回[self.fileList count],那么您需要做的就是reloadData。 iOS将负责删除任何旧的,现在已删除的行。但是通过取出cell==nil,你不会让iOS重用旧单元格,因此你会浪费内存。除非你有充分的理由摆脱cell==nil逻辑,否则你不应该。

你的代码片段中有一个奇怪的语句片段:

    objectAtIndex:indexPath.row],self.fileList.count,indexPath.row);

我不知道该行应该是什么,因此您可能想澄清您的代码示例。

总而言之,您的解决方案效率低下,可能会掩盖代码中的其他一些问题。我想知道,例如,为了简化你的帖子,你是否删除了cellAtRowForIndexPath的一些显着部分。值得注意的是,您是否在真实UILabel中创建了任何cellAtRowForIndexPath控件或类似内容?也许你可以和我们分享完整的方法。当我在reloadData之后看到不合需要的结果时,通常是因为用户在cellAtRowForIndexPath中创建了一些控件,但在重新使用出列的单元格时未能解释这一事实。典型的解决方案是,如果您将子视图添加到UITableViewCell,则为其分配tag属性,如果您正在重新使用出列的单元格,则使用viewWithTag检索这些已创建的子视图。请参阅Table View Programming Guide中自定义单元格讨论中tag属性的使用。

也许这不是问题,但无论如何,当您注释掉cell == nil条件逻辑时,代码的行为会有所不同,这意味着您在cellForRowAtIndexPath方法的详细信息中遇到了一些问题。也许你可以和我们分享完整的方法,因为简化的例子没有明显的错误(除了那些零碎的代码行)。