@ Опубликованная оболочка свойства и ее wrappedValue - PullRequest
1 голос
/ 10 октября 2019

Когда вы определяете свою собственную оболочку свойств, вы должны указать нестатическое свойство с именем 'wrappedValue' . Например:

@propertyWrapper
struct MyPropertyWrapper<Value> {
    var value: Value
}

с кодом выше, компилятор жалуется, что:

Тип оболочки свойства 'MyPropertyWrapper' не содержит нестатического свойства с именем 'wrappedValue'

Итак, вы можете исправить ошибку, просто выполнив:

@propertyWrapper
struct MyPropertyWrapper<Value> {
    var value: Value

    var wrappedValue: Value {
        get {
            value
        }
        set {
            value = newValue
        }
    }
}

Просто приведу несколько примеров, это верно для @State:

@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
@propertyWrapper public struct State<Value> : DynamicProperty {

    /// The current state value.
    public var wrappedValue: Value { get nonmutating set }
}

то же самоедля @Binding:

@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
@propertyWrapper @dynamicMemberLookup public struct Binding<Value> {

    /// The value referenced by the binding. Assignments to the value
    /// will be immediately visible on reading (assuming the binding
    /// represents a mutable location), but the view changes they cause
    /// may be processed asynchronously to the assignment.
    public var wrappedValue: Value { get nonmutating set }
}

и пр. Но оболочка свойства @Published не имеет обернутого значения:

@available(iOS 13.0, OSX 10.15, tvOS 13.0, watchOS 6.0, *)
@propertyWrapper public struct Published<Value> {

    /// Initialize the storage of the Published property as well as the corresponding `Publisher`.
    public init(initialValue: Value)

    /// A publisher for properties marked with the `@Published` attribute.
    public struct Publisher : Publisher {

        /// The kind of values published by this publisher.
        public typealias Output = Value

        /// The kind of errors this publisher might publish.
        ///
        /// Use `Never` if this `Publisher` does not publish errors.
        public typealias Failure = Never

        /// This function is called to attach the specified `Subscriber` to this `Publisher` by `subscribe(_:)`
        ///
        /// - SeeAlso: `subscribe(_:)`
        /// - Parameters:
        ///     - subscriber: The subscriber to attach to this `Publisher`.
        ///                   once attached it can begin to receive values.
        public func receive<S>(subscriber: S) where Value == S.Input, S : Subscriber, S.Failure == Published<Value>.Publisher.Failure
    }

    /// The property that can be accessed with the `$` syntax and allows access to the `Publisher`
    public var projectedValue: Published<Value>.Publisher { mutating get }
}

Я здесь кое-что упускаю наверняка, так как компилятор не позволит вам создать оболочку свойства без wrappedValue,Какая разница в этом случае по отношению к другим обёрткам свойств?

1 Ответ

1 голос
/ 11 октября 2019

Код, который вы показали, не является фактической реализацией из @Published - это просто общедоступный интерфейс. Если вы вставите этот код в Xcode, вы получите ту же ошибку относительно wrappedValue среди других;Этот код не компилируется.

wrappedValue имеет уровень доступа internal - поэтому мы можем предположить, что фактическая реализация @Published объявляет что-то вроде interval var wrappedValue:Value. Это удовлетворяет требованию оболочки свойства, но означает, что wrappedValue не виден за пределами его структуры.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...