UITableViewDelegate搭配UITableViewDiffableDataSource跨Target不生效
问题原因
该问题由Swift跨模块静态派发机制与Objective-C运行时协议方法检测逻辑冲突导致:
- 在独立Target中定义继承自
UITableViewDiffableDataSource的Base类时,如果仅声明遵循UITableViewDelegate协议、不实现任何协议可选方法,Swift编译器不会在该Target生成的类元数据中,为Base类写入UITableViewDelegate相关方法的响应标记。 - 其他Target中的子类继承Base类并实现
UITableViewDelegate可选方法时,由于UITableView底层为Objective-C实现,查询delegate方法响应能力时会沿父类链向上检索到跨模块定义的Base类,检测到Base类元数据无对应代理方法的响应标记后,会直接判定当前delegate不响应该方法、终止查找流程,最终子类实现的所有代理方法都无法触发。
解决方案
任选其一即可修复:
- 在Base类所在的Target中,为Base类实现至少一个
UITableViewDelegate可选方法,空实现也可生效,示例:
func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { UITableView.automaticDimension }
添加后编译器会为Base类注入UITableViewDelegate协议的方法响应标识,跨模块子类实现的其余代理方法即可被Objective-C运行时正常识别、触发。
- 将
UITableViewDelegate协议的遵循声明从跨模块Base类移除,挪到实际实现代理方法的子类所在Target中声明。 - 重写Base类的
responds(to:)方法,手动校验子类是否实现对应代理方法并返回正确的布尔值,该方案维护成本较高,不推荐优先使用。
内容的提问来源于stack exchange,提问作者Михаил Назаров
相关产品推荐
相关产品推荐

