Swift 4中MVC模式下模型与控制器的交互问题咨询
Swift 4 BLE应用MVC交互流程:合理性分析与优化建议
嘿,针对你现在用Swift 4开发BLE交互应用的MVC流程问题,我来给你拆解下合理性,再分享几个更优的实现思路~
当前流程的合理性
你现在的流程:蓝牙收数据→存模型→模型发通知→控制器响应;控制器修改模型→同步数据。这个逻辑本身是符合MVC职责划分的:
- 模型专注于数据存储和状态管理,通过通知中心对外广播变更,守住了「单一职责」的原则
- 控制器作为模型的持有者,处理用户交互并同步修改到模型,也符合MVC里控制器作为中间层的定位
不过通知中心也有几个小坑:
- 通知是全局广播的,很容易出现无关代码误监听,后期排查问题会头疼
- 通知的发送和接收完全解耦,导致代码里的依赖关系不明确,新人接手时很难快速理清数据流向
- 如果控制器没正确移除观察者,还容易引发内存泄漏
更优的实现方案
结合Swift 4的特性,推荐几个更可控的替代方案:
1. 委托模式(Delegation)—— 最常用的解耦方式
这是iOS开发里最经典的一对一/一对多通知方案,比通知中心的依赖关系明确得多:
- 给模型定义一个委托协议,约定数据变更的回调方法
- 让控制器遵守这个协议,成为模型的委托对象
- 模型数据更新时,直接调用委托方法通知控制器
示例代码:
// 定义委托协议 protocol BluetoothDataModelDelegate: AnyObject { func dataModel(_ model: BluetoothDataModel, didUpdateWith newData: Data) } // 模型类 class BluetoothDataModel { // 用weak避免循环引用 weak var delegate: BluetoothDataModelDelegate? func processBLEData(_ incomingData: Data) { // 存储/解析数据的逻辑 // ... // 通知委托的控制器 delegate?.dataModel(self, didUpdateWith: incomingData) } } // 控制器类 class BLEController: UIViewController, BluetoothDataModelDelegate { private let dataModel = BluetoothDataModel() override func viewDidLoad() { super.viewDidLoad() // 设置委托 dataModel.delegate = self } // 实现委托方法,更新UI func dataModel(_ model: BluetoothDataModel, didUpdateWith newData: Data) { // 处理UI更新逻辑,比如刷新表格、更新标签 // ... } // 控制器主动修改模型 func updateModel(with newValue: String) { dataModel.updateLocalData(newValue) } }
优点:依赖关系清晰,不会有全局广播的混乱,内存泄漏风险也更低(因为用了weak修饰委托)
2. 闭包回调——轻量的一对一通知
如果你的模型只需要给一个控制器发通知,闭包会是更简洁的选择:
- 在模型里定义一个闭包属性,用于数据变更的回调
- 控制器初始化模型时,设置这个闭包的具体实现
- 模型数据更新时直接调用闭包
示例代码:
class BluetoothDataModel { // 定义回调闭包 var onDataUpdated: ((Data) -> Void)? func processBLEData(_ incomingData: Data) { // 存储/解析数据 // ... // 触发回调 onDataUpdated?(incomingData) } } class BLEController: UIViewController { private let dataModel = BluetoothDataModel() override func viewDidLoad() { super.viewDidLoad() // 设置闭包,注意用[weak self]避免循环引用 dataModel.onDataUpdated = { [weak self] newData in guard let self = self else { return } // 更新UI逻辑 // ... } } }
优点:代码更紧凑,适合简单的一对一通知场景,不用额外定义协议
3. 尝试MVVM模式(适合复杂应用)
如果你的应用后续会增加更多功能,MVVM能帮你进一步拆分逻辑,让控制器更轻量化:
- 模型还是负责BLE数据的存储和解析
- 新增ViewModel层,作为模型和视图的中间层,处理数据转换、业务逻辑
- ViewModel通过闭包或委托通知控制器更新UI,控制器只负责绑定ViewModel和视图,不用处理复杂业务
这种模式能让代码更易测试,也更利于后期扩展
总结
你当前的MVC流程是完全合理且符合规范的,但如果想提升代码的可维护性和可读性,优先推荐委托模式(适合多场景、需要明确依赖的情况)或闭包回调(适合简单的一对一通知)。如果应用规模会变大,逐步迁移到MVVM模式会是更长远的选择。
内容的提问来源于stack exchange,提问作者BEPP1
相关产品推荐
相关产品推荐

