3.5 KiB
3.5 KiB
DiffableDataSource 迁移记录(阶段性回退)
时间:2025-09-23
背景
- 目标:将房间消息公屏迁移到 UITableViewDiffableDataSource(iOS 13+)。
- 核心组件:
XPMessageItem
、XPMessageDataSourceManager
、XPRoomMessageContainerView
、XPRoomViewController
。
已完成
- 新增
XPMessageItem
(实现 NSCopying/isEqual/hash/description)。 - 新增
XPMessageDataSourceManager
:串行队列封装、读写隔离;修复了在队列内访问只读属性导致的递归/死锁,改用_allMessages/_chatMessages/_giftMessages
;新增addMessageSync:
用于快照直后立刻刷新。 XPRoomMessageContainerView
:- 增加 DiffableDataSource 支持:
setupDiffableDataSource
、addMessageWithDiffableDataSource:
、updateDiffableDataSourceSnapshot
、scrollToBottomWithDiffableDataSource:
、changeTypeWithDiffableDataSource:
。 - 绑定
tableView.dataSource = diffableDataSource
。 - 修正行高计算在 Diffable 模式下基于
dataSourceManager
。 - 解析/建模移动到主线程,避免 parser 内创建 UIView 触发 MTC。
- 增加 DiffableDataSource 支持:
XPRoomViewController
:统一分发入口distributeMessage:toContainer:
,在启用时路由到container.messageListView addMessageWithDiffableDataSource:
。
遇到的问题
- Main Thread Checker:parser 内创建
NetImageView
,后台线程调用崩溃 → 已将解析迁至主线程。 - 数据源递归死锁:在队列内通过 getter 访问只读数组,getter 内
dispatch_sync
→ 已用 ivar 替代。 - API 调用不兼容:
appendItems:toSection:
(Swift 签名)在 Obj‑C 不可用 → 改为appendItemsWithIdentifiers:intoSectionWithIdentifier:
。 - UI 不显示:日志显示 snapshot item 数量正确、cellProvider 触发,但 cell 行高与旧数组耦合,渲染为空 → 已在 Diffable 模式下改为从
dataSourceManager
读取。 - 仍存在:
- 部分 cell 样式依赖旧数据流与时序;
- 插入数据不全(需要进一步梳理 parser→model→item 的丢弃路径与过滤条件)。
现状与决策
- 暂时关闭 DiffableDataSource(
XPRoomViewController.useDiffableDataSource
返回 NO,XPRoomMessageContainerView.useDiffableDataSource = NO
),回退旧方案,确保稳定性。
后续建议(待恢复时)
- 将 parser 改为纯数据产出(不创建 UIView/Attachment UI),UI 组件在 cell 渲染时构造。
- 为
XPMessageItem
/XPMessageInfoModel
增加单元测试与快照测试,覆盖典型 first/second 组合、礼物/文本/通知。 - 建立统一的高度计算服务,消除表与数据源的耦合分支。
- 快照构建前后加一致性校验(section/items 数量、索引有效性)。
- 按功能开关分阶段恢复:先纯文本 → 表情 → 通知 → 礼物 → 特殊 cell。
变更点列表(代码)
YuMi/Modules/YMRoom/View/MessageContainerView/Model/XPMessageItem.{h,m}
新增。YuMi/Modules/YMRoom/View/MessageContainerView/Model/XPMessageDataSourceManager.{h,m}
新增与修复(addMessageSync、ivar 访问等)。YuMi/Modules/YMRoom/View/MessageContainerView/XPRoomMessageContainerView.m
多处新增/修改(Diffable 支持、主线程解析、行高来源切换、dataSource 绑定)。YuMi/Modules/YMRoom/View/XPRoomViewController.m
新增distributeMessage:toContainer:
,并默认关闭 Diffable。
回退开关位置
XPRoomViewController - (BOOL)useDiffableDataSource
→ NOXPRoomMessageContainerView.useDiffableDataSource
→ NO
记录人:系统自动