You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何从UpNextViewModel观察UpNextService属性并同步isShuffled状态?

如何让UpNextViewModel与UpNextService的isShuffled属性保持同步?

核心思路是让UpNextService作为唯一状态源,ViewModel不维护独立的isShuffled副本,而是通过计算属性直接代理到Service的对应属性,结合Swift的@Observable特性实现自动同步。

具体实现步骤

  1. 修改UpNextViewModel,用计算属性绑定Service的isShuffled
    把ViewModel里的独立isShuffled字段替换为计算属性,读写操作直接转发给Service:
@Observable
class UpNextViewModel {
    var repeatStatus: RepeatStatus = .none

    // 双向绑定Service的isShuffled,无本地状态冗余
    var isShuffled: Bool {
        get { upNextService.isShuffled }
        set { upNextService.isShuffled = newValue }
    }
    
    let upNextService: UpNextService
    
    init(upNextService: UpNextService) {
        self.upNextService = upNextService
    }
}
  1. 保持UpNextService的@Observable特性
    原Service的@Observable修饰保留,确保当它的isShuffled变化时,所有依赖的ViewModel和视图都能收到更新通知:
@Observable
class UpNextService {
    var isShuffled = false // 唯一可信的状态源
    
    // 原有方法保持不变(修正异步方法的语法)
    func writeItems() async throws {
        let url = isShuffled 
            ? FileManager.shuffledUpNextQueueURL 
            : FileManager.originalUpNextQueueURL

        let (data, _) = try await URLSession.shared.data(from: url)
        
        // 写入逻辑
    }
    
    func readItems() async throws -> [UpNextItem] {
        let url = isShuffled 
            ? FileManager.shuffledUpNextQueueURL 
            : FileManager.originalUpNextQueueURL

        let (data, _) = try await URLSession.shared.data(from: url)
        
        // 读取逻辑
        return [] // 根据实际逻辑返回解析后的数据
    }
    
    func removeItem(at index: Int) async throws {
        let url = isShuffled 
            ? FileManager.shuffledUpNextQueueURL 
            : FileManager.originalUpNextQueueURL

        let (data, _) = try await URLSession.shared.data(from: url)
        
        // 删除逻辑
    }
}

方案优势

  • 无状态冗余:ViewModel不存独立的isShuffled值,完全依赖Service的唯一数据源,从根源避免不一致
  • 自动同步:无论是通过ViewModel修改,还是其他直接操作Service的地方修改isShuffled,所有监听该属性的视图(不管关联哪个ViewModel)都会自动刷新
  • 逻辑集中:状态变更的额外逻辑可以统一放在Service的isShuffled的didSet中,比如:
@Observable
class UpNextService {
    var isShuffled = false {
        didSet {
            if isShuffled != oldValue {
                // 状态变化时执行额外操作,比如日志记录、队列重排
            }
        }
    }
    
    // ...原有方法
}

注意事项

  • 确保所有ViewModel注入的是同一个UpNextService实例(可通过依赖注入容器、单例或SwiftUI环境变量传递),否则多个Service实例会导致状态分散
  • ViewModel只负责转发状态和处理视图交互逻辑,业务逻辑尽量放在Service中,保持ViewModel轻量化

内容的提问来源于stack exchange,提问作者User95797654974

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.13 21:23:20