计算属性设置为可选获取为非可选

时间:2021-03-17 04:27:23

标签: ios swift

我想创建计算属性:

  var status: Int? {
    get { return _status }
    set {
      if let newValue = newValue {
        updateStatus(newValue: newValue)
      }
    }
  }

_status 在哪里:Int。 但我想进入非可选。

user.status 没有 !

最好的方法是什么?

2 个答案:

答案 0 :(得分:2)

您可以提供这样的默认值

    private var _status: Int

    var status: Int! {
    get {
        return _status
    }
    set {
        if let newValue = newValue {
            _status = newValue
        } else {
            _status = 0
        }
    }
}

答案 1 :(得分:1)

您不能使用单个属性来实现,因为 get 和 set 访问器需要完全匹配类型。最接近的是属性包装器,使用 $ 完成所有设置。

@objc final class ObjectiveCObject: NSObject {
  var status = 0
}

struct StatusThingy {
  @DefaultWhenSetToNil var status: Int
}

let object = ObjectiveCObject()

let thingy = StatusThingy(
  status: .init(
    wrappedValue: .init { object.status } set: { object.status = $0 },
    default: object.status
  )
)

thingy.status // 0
thingy.$status = 1
thingy.status // 1
thingy.$status = nil
thingy.status // 0
@propertyWrapper struct DefaultWhenSetToNil<Value> {
  @Computed private(set) var wrappedValue: Value
  let `default`: Value

  var projectedValue: Value? {
    get { wrappedValue }
    nonmutating set { wrappedValue = newValue ?? `default` }
  }
}
/// A workaround for limitations of Swift's computed properties.
///
/// Limitations of Swift's computed property accessors:
/// 1. They are not mutable.
/// 2. They cannot be referenced as closures.
@propertyWrapper public struct Computed<Value> {
  public typealias Get = () -> Value
  public typealias Set = (Value) -> Void

  public init(
    get: @escaping Get,
    set: @escaping Set
  ) {
    self.get = get
    self.set = set
  }

  public var get: Get
  public var set: Set

  public var wrappedValue: Value {
    get { get() }
    nonmutating set { set(newValue) }
  }

  public var projectedValue: Self {
    get { self }
    set { self = newValue }
  }
}
相关问题