「购物车数据同步遇难题?iOS跨模块通信三种实战方案」
日期:2025-05-28 00:06:32 •原创
场景痛点:用户点击商品页"加购"按钮后,如何实时更新侧边栏购物车角标?
(某电商App迭代中遇到的真实开发需求)
方案一:NotificationCenter轻量广播(适用于简单数据传递)
swift复制// 商品详情页发出购买信号 NotificationCenter.default.post( name: .didUpdateCart, object: ["skuID": "12345", "count": 3] ) // 侧边栏购物车监听 NotificationCenter.default.addObserver( self, selector: #selector(updateCartBadge), name: .didUpdateCart, object: nil ) @objc func updateCartBadge(_ notification: Notification) { guard let info = notification.object as? [String: Any] else { return } badgeLabel.text = "\(info["count"] ?? 0)" }
??适用场景??:跨多层级页面通信、非强关联模块
??避坑指南??:务必在deinit中移除观察者,避免内存泄漏
方案二:Closure回调链(精准控制交互流程)
swift复制// 定义购物车服务协议 protocol CartServiceable { var onCartUpdate: ((Int) -> Void)? { get set } } class CartManager: CartServiceable { static let shared = CartManager() var onCartUpdate: ((Int) -> Void)? func addToCart(itemID: String) { // 网络请求... onCartUpdate?(currentCount + 1) } } // 商品页触发加购 CartManager.shared.addToCart(itemID: "12345") // 侧边栏绑定更新 CartManager.shared.onCartUpdate = { [weak self] count in self?.badgeLabel.text = "\(count)" }
??适用场景??:1对1精准通信、需要处理异步回调结果
??性能优化??:使用weak避免循环引用,回调中必须切主线程更新UI
方案三:ResponderChain责任链(复杂界面层级穿透)
swift复制// 自定义购物车事件 class CartEvent: UIEvent { var operation: OperationType var payload: [String: Any] override func sendEvent(_ event: UIEvent) { UIApplication.shared.sendAction( #selector(handleCartEvent(_:)), to: nil, // 自动寻找响应者 from: self, for: event ) } } // 侧边栏控制器响应 override func canHandle(_ event: UIEvent) -> Bool { return event is CartEvent } @objc func handleCartEvent(_ event: CartEvent) { switch event.operation { case .addItem: badgeLabel.text = "\(event.payload["count"] ?? 0)" // 其他操作处理... } }
??适用场景??:多层嵌套的复杂UI结构、需要事件穿透
??开发技巧??:结合泛型定义统一事件处理接口,配合extension扩展默认实现
方案选型决策树
- 是否需要广播到多个接收方 → NotificationCenter
- 是否涉及异步操作/网络请求 → Closure回调链
- 是否在复杂视图层级中传递 → ResponderChain
- 是否需要类型安全 → 改用Combine框架的PassthroughSubject
扩展方案:基于SwiftUI的跨组件通信
(针对适配SwiftUI的混合开发项目)
swift复制@Observable class CartStore { var itemCount = 0 } struct AddToCartButton: View { @Environment(CartStore.self) private var cart var body: some View { Button("加购") { cart.itemCount += 1 } } } struct CartBadge: View { @Environment(CartStore.self) private var cart var body: some View { Text("\(cart.itemCount)") } }
??技术演进建议??:当项目使用Combine或RxSwift时,建议采用PassthroughSubject
或PublishSubject
实现响应式通信
本文由嘻道妙招独家原创,未经允许,严禁转载