我正在写一个图像编辑工具。我有一个显示文档文件夹内容的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;
}
然而,这是一种有效的工作方式吗?这会导致我的性能问题吗?
答案 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
方法的详细信息中遇到了一些问题。也许你可以和我们分享完整的方法,因为简化的例子没有明显的错误(除了那些零碎的代码行)。