1

我正在编写一个图像编辑工具。我有一个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

4 回答 4

2

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

检查cell == nil是为了查看是否已经有一个单元格可以重复使用。如果不是这样nil,您将不得不重新创建它。

所以就像我现在说的,你没有使用 Apple 为UITableView. 它是为了表演而存在的,所以如果我是你,我仍然会有那张支票。

于 2012-09-11T12:01:22.560 回答
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];
于 2012-09-11T12:58:17.793 回答
0

那是绝对安全的,您可以省略dequeueReusableCellWithIdentifier调用并在不重用标识符的情况下创建单元格。

当然,这意味着您不会重用单元格,但我发现如果单元格不大量使用内存但占用大量 UI 表示逻辑,这是一种有用的方法。在这种情况下,我可以负责单元缓存并手动执行,这会与重用标识符逻辑冲突。

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

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

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

于 2012-09-11T12:32:39.760 回答
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?也许您可以与我们分享完整的方法。当我在 a 之后看到不良结果时reloadData,通常是因为用户在其 中创建了一些控件cellAtRowForIndexPath,但在重用出列单元格时未能考虑到这一事实。典型的解决方案是,如果您将子视图添加到 a UITableViewCell,则为它们分配tag属性,并且如果您正在重用出列单元格,则使用viewWithTag. 见使用tag在Table View Programming Guide中讨论自定义单元格的属性。

也许这不是问题,但无论如何,当您注释掉cell == nil条件逻辑时您的代码行为不同这一事实意味着您的方法细节存在问题cellForRowAtIndexPath。也许您可以与我们分享完整的方法,因为简化的示例没有任何明显错误(除了那段零碎的代码行)。

于 2012-09-11T12:39:10.530 回答