为计算属性添加@Published 行为 [英] Add @Published behaviour for computed property

查看:20
本文介绍了为计算属性添加@Published 行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试制作一个 ObservableObject,它具有包装 UserDefaults 变量的属性.

I am trying to make a ObservableObject that has properties that wrap a UserDefaults variable.

为了符合ObservableObject,我需要用@Published 包裹属性.不幸的是,我无法将其应用于计算属性,因为我用于 UserDefaults 值.

In order to conform to ObservableObject, I need to wrap the properties with @Published. Unfortunately, I cannot apply that to computed properties, as I use for the UserDefaults values.

我怎样才能让它工作?我该怎么做才能实现 @Published 行为?

How could I make it work? What do I have to do to achieve @Published behaviour?

推荐答案

更新:有了EnclosureSelf下标就可以了!

Updated: With the EnclosingSelf subscript, one can do it!

就像一个魅力!

import Combine
import Foundation

class LocalSettings: ObservableObject {
  static var shared = LocalSettings()

  @Setting(key: "TabSelection")
  var tabSelection: Int = 0
}

@propertyWrapper
struct Setting<T> {
  private let key: String
  private let defaultValue: T

  init(wrappedValue value: T, key: String) {
    self.key = key
    self.defaultValue = value
  }

  var wrappedValue: T {
    get {
      UserDefaults.standard.object(forKey: key) as? T ?? defaultValue
    }
    set {
      UserDefaults.standard.set(newValue, forKey: key)
    }
  }

  public static subscript<EnclosingSelf: ObservableObject>(
    _enclosingInstance object: EnclosingSelf,
    wrapped wrappedKeyPath: ReferenceWritableKeyPath<EnclosingSelf, T>,
    storage storageKeyPath: ReferenceWritableKeyPath<EnclosingSelf, Setting<T>>
  ) -> T {
    get {
      return object[keyPath: storageKeyPath].wrappedValue
    }
    set {
      (object.objectWillChange as? ObservableObjectPublisher)?.send()
      UserDefaults.standard.set(newValue, forKey: object[keyPath: storageKeyPath].key)
    }
  }
}

这篇关于为计算属性添加@Published 行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆