Nis*_*n29 1 iphone objective-c uitableview ios ios9
我有一个UITableview,它有一些历史.我使用自定义单元格来处理标签,图像和按钮的显示.里面大约有50排UITableview.但问题是当Tableview向上滚动时,第一个显示的行下面的行的值已经改变了.不确定Tableview究竟发生了什么.
static NSString *CellIdentifier = @"HistoryCell";
cellHistory = [self.notificationTableView dequeueReusableCellWithIdentifier:CellIdentifier forIndexPath:indexPath];
[cellHistory.label clearActionDictionary];
//Step 2: Define a selection handler block
void(^handler)(FRHyperLabel *label, NSString *substring) = ^(FRHyperLabel *label, NSString *substring)
{
    [self userNameTapped:[[[[self.arrayHistory objectAtIndex:indexPath.row] objectForKey:Details] objectForKey:@"key"] objectForKey:@"key"]];
};
//Step 3: Add link substrings
[cellHistory.label setLinksForSubstrings:@[userName] withLinkHandler:handler];
return cellHistory;
以下答案涉及具体实施,而不是设计.使用样板代码NSFetchedResultsController可以防止这个错误首先发生.(Apple文档).不惜一切代价,避免操作一旦返回的单元格cellForRowAtIndexPath:你不拥有它.
1.重用的单元格不会被缓存
特别担心的是这条线:
[self.arrayHistory objectAtIndex:indexPath.row]
不是因为那个特定的实例,而是因为它让我认为你在这个类的其他地方做出假设:UITableViewCell检索过的via dequeueReusableCellWithIdentifier只不过是一个瞬态对象,纯粹UITableView用于展示.
随着时间的推移,同一个单元实例将具有多个indexPath:这样的单元可能不会在更进一步的日期被缓存或操纵.一旦作为最后一个语句返回cellForRowAtIndexPath,它可能无法再次访问,是否由外部指针通过某种异步方法保留.总是考虑通过获得的高速缓存的表视图的索引路径dequeueReusableCellWithIdentifier作为陈旧.
不要不修改一次返回的单元格的内容.遵循下面Losiowaty概述的正确设计.
如果你必须修改已经返回到表视图的单元格的内容,那么为了更好的判断,你必须为此专用一个持久单元格,例如,使用一个字典UITableViewCell.dequeueReusableCellWithIdentifier除非该标识符专用于该单元,否则您不能在这样的单元上调用; 虽然大数据集的内存效率很高,但它可以保证不重复使用单元.
2.不要猜 tableview
- (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    cellHistory = [self.notificationTableView // etc.
正确的逻辑UITableViewDataSource cellForRowAtIndexPath是使用传递给你的参数:
- (UITableViewCell *)tableView:(UITableView *)tableView
         cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    cellHistory = [tableView // etc.
3.重复使用干净的再生细胞
假设您已经掌握了使用的回收副作用dequeueReusableCellWithIdentifier,并确保您不会对不同类型的细胞进行交叉授粉,您可能需要清理重复使用的细胞(感谢Timur Bernikowich的评论):
func prepareForReuse() {
    super.prepareForReuse()
    // reset attributes of the cell that are not related to content
}
4.首先反思
总是喜欢我曾经做过的错误,它曾经在以前的操作系统中工作过.虽然第二个命题通常是正确的,但总的来说,历史可以让你思考它曾经在天堂如何工作.
相反,我通常将这些情况视为一个肯定的迹象,我正在做一些可怕的错误,我很幸运能够解决问题.
5.尊重命名约定
虽然我很佩服你在方法中传递块
- (void)setLinksForSubstrings:(NSArray*)string withLinkHandler:(void(^)(FRHyperLabel *label, NSString *substring))handler {}
我对这个Details物体的性质有点不屑一顾userName,更不用说4个括号了[self userNameTapped:[[[[.如果我被抛弃,其他工程师在第一次接触您的代码时可能会这样做.
从上下文来看,我无法推导出变量,常量,静态,实例属性等等.您的单元格很可能在该级别上被混淆(您可能正在重复使用您假设为本地或基于堆栈的值,但不是).
我可以建议使用a typedef作为块,采用大写一致性,并避免嵌套[太深.将代码与样板UITableView代码进行比较只需要做一些非常重要的工作,只是为了消除噪音.
| 归档时间: | 
 | 
| 查看次数: | 1159 次 | 
| 最近记录: |