配置Combine执行顺序:State与LineView联动绘图的参数同步问题
基于Combine构建State与LineView的绘图依赖管道
核心设计思路
- 以
State的三个核心属性(颜色、线宽、点集)作为Combine数据源,确保任一属性变化时都能获取完整的最新State实例 - 基于完整
State生成黑盒Parameters结构体,避免拆分参数导致的不一致问题 - 根据触发更新的属性类型,定向调用对应的绘图方法,同时保证传入的是最新的
Parameters
代码实现
基础定义
import Combine import UIKit // 用户状态类,存储绘图相关配置与点集 class State: ObservableObject { @Published var lineColor: UIColor = .black @Published var lineWidth: CGFloat = 1.0 @Published var points: [CGPoint] = [] } // 黑盒绘图参数结构体,仅能通过State实例构建 struct Parameters { let color: UIColor let width: CGFloat let points: [CGPoint] init(from state: State) { self.color = state.lineColor self.width = state.lineWidth self.points = state.points } } // 负责绘图的视图类 class LineView: UIView { // 仅更新线条颜色的方法 func recolorLine(with params: Parameters) { // 此处实现颜色重绘逻辑 setNeedsDisplay() } // 更新线宽与点集的方法 func reshapeLine(with params: Parameters) { // 此处实现线宽、点集重绘逻辑 setNeedsDisplay() } }
Combine管道构建
// 控制器类,负责关联State与LineView的逻辑 class LineController { private let state: State private let lineView: LineView private var cancellables = Set<AnyCancellable>() init(state: State, lineView: LineView) { self.state = state self.lineView = lineView setupCombinePipeline() } private func setupCombinePipeline() { // 1. 合并三个属性的更新事件,每次变化都输出完整的最新State let stateUpdates = Publishers.Merge3( state.$lineColor.map { _ in self.state }, state.$lineWidth.map { _ in self.state }, state.$points.map { _ in self.state } ) // 2. 生成全局唯一的最新Parameters流,避免重复构建 let paramsUpdates = stateUpdates .map { Parameters(from: $0) } .share() // 3. 按属性更新类型分发到对应绘图方法 // 颜色变化时调用recolorLine state.$lineColor .withLatest(from: paramsUpdates) .sink { [weak self] _, params in self?.lineView.recolorLine(with: params) } .store(in: &cancellables) // 线宽变化时调用reshapeLine state.$lineWidth .withLatest(from: paramsUpdates) .sink { [weak self] _, params in self?.lineView.reshapeLine(with: params) } .store(in: &cancellables) // 点集变化时同时调用两个绘图方法 state.$points .withLatest(from: paramsUpdates) .sink { [weak self] _, params in self?.lineView.recolorLine(with: params) self?.lineView.reshapeLine(with: params) } .store(in: &cancellables) } }
逻辑说明
Merge3确保任一属性更新时,都会输出完整的最新State,彻底避免了参数拆分导致的不一致问题share()操作符保证Parameters只在状态变化时构建一次,所有订阅者共享同一个实例,提升性能withLatest(from:)确保每个属性更新事件触发时,都能获取到基于完整State生成的最新Parameters,完全符合需求中的调用规则
内容的提问来源于stack exchange,提问作者Artem Goldenberg
相关产品推荐
相关产品推荐

