UITableView重用机制与数据源同步

一 重用机制

1 问题

UITablevView是开发中最常用的实现滚动列表的方案之一, 列表的具体内容载体由UITablevViewCell, 负责一个列表可能有成千上万个cell,然而iOS设备的内存是有限的,无限制的创建cell将会耗尽设备内存进而导致程序crash.
苹果为了解决此问题, 设计出一种既能展示大量数据又能节省内存的机制即重用机制.

2 原理

UITableView内部维护了一个重用缓存池队列, 当屏幕上cell移动出屏幕后, 系统自动把它放入重用池中, 当dataSource下一条数据要求呈现时, 系统会去重用池中查找是否有可重用对象, 如果有则拿出复用, 没有则走创建流程. 同时, 为了避免避免列表中有多种自定义UITableViewCell, 苹果通过绑定重用标识符(identifier)来查找对应的cell类型.
在这里查看官方文档

UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:identifier];
//如果重用池当中没有可重用的cell,那么创建一个cell
if (cell == nil) {
    cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:identifier];
}

这里A1到A7视为同一个标识符,虚线是可视区域,当A1滑出可视区域的时候会放入重用池A,A7根据标识符从备用池取出一个可重用的cell,这样就达到了重用的一个目的
原理图

3 模拟重用池

字母索引条的小demo
创建使用中和重用池中的对象集合

_waitUsedQueue = [NSMutableSet set];
_usingQueue = [NSMutableSet set];

取出一个可重用的视图

- (UIView *)dequeueReusableView{
    UIView *view = [_waitUsedQueue anyObject];
    if (view == nil) {
        return nil;
    } else {
        // 从重用池队列中移除,添加到使用队列
        [_waitUsedQueue removeObject:view];
        [_usingQueue addObject:view];
        return view;
    }
}

添加视图到重用池

- (void)addUsingView:(UIView *)view {
    if (view == nil) {
        return;
    }
    [_usingQueue addObject:view];
}

将当前所有视图移动到重用池中

- (void)reset{
    UIView *view = nil;
    while ((view = [_usingQueue anyObject])) {
        // 从使用中队列移除
        [_usingQueue removeObject:view];
        // 加入等待使用的队列
        [_waitUsedQueue addObject:view];
    }
}

二 数据源同步

1 问题

删除列表一条数据, 崩溃!
本质是tableView在多线程的情况下修改或者访问数据源后的如何同步?

[self.dataSource removeObjectAtIndex:indexPath.row];
[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationNone];

2 解决方案

2.1 并发访问&数据拷贝

  • 用户删除一条数据, reloadUI
  • 异步通知子线程数据同步
  • 异步数据回调, reloadUI
  • 缺点: 拷贝操作, 占用大量内存, 浪费CPU性能
    在这里插入图片描述

2.2 串行访问

  • 异步串行队列做网络请求, 数据解析, 预排版
  • 用户删除数据
  • 异步通知子线程数据同步
  • 回调, reloadUI
    在这里插入图片描述

我是个写代码的小学生, 如有不足, 万望不吝指教

发布了4 篇原创文章 · 获赞 1 · 访问量 141

猜你喜欢

转载自blog.csdn.net/weixin_43837354/article/details/104643784