PropertyWrapper - Global является внешним, но не имеет внешней или слабой связи - PullRequest
0 голосов
/ 20 марта 2020

Я работаю с Property wrappers в проекте, который разделен на несколько Swift package модулей, зависящих друг от друга. Я использовал свои собственные оболочки свойств в коде, но я хочу переключиться на Combine, так как он содержит много функций, аналогичных моим property wrappers. В процессе конвертации я часто сталкиваюсь с проблемой компилятора:

Abort trap: 6 с сообщением об ошибке: Global is external, but doesn't have external or weak linkage!.

В качестве первого шага я решил избавиться от этой ошибки, все еще используя свой property wrappers, потому что она может возникнуть даже там, но мне удалось избавиться от нее. Но не в чистом виде, и я хотел бы получить больше знаний о том, что происходит, поэтому я мог бы перейти к Combine позже - с теми же ошибками.

Хорошо, так что избавиться от Abort trap: 6 с моим старым property wrappers Мне нужно было переключить способ использования этого свойства в некоторых модулях. Вместо того, чтобы писать и читать напрямую, я обращаюсь к нему с помощью $ property.wrappedValue. Тогда это работает, но это очень уродливо в коде, и отчасти отрицает смысл использования property wrapper. Может кто-нибудь объяснить мне, почему эта ошибка происходит? В некоторых модулях я могу использовать его напрямую без проблем. Я понятия не имею, что происходит, и что я могу сделать, чтобы решить эту проблему. Я пытался преобразовать множество похожих свойств с помощью Combine, и я просто получаю больше этих ошибок, и на самом деле я даже не смог их устранить подобным образом.

Скажите, пожалуйста, что это за ошибка, почему она возникает и что я могу сделать, чтобы ее устранить. enter image description here

Если его поможет, вот как определяется это свойство оболочки:

@propertyWrapper
public class ObservableChangedValue<Value: Equatable>: Observable<Value> {

    public var projectedValue: ObservableChangedValue { self }

    public override var wrappedValue: Value {
        get { super.wrappedValue }
        set { super.wrappedValue = newValue }
    }

    override func shouldExecuteNotifications(oldValue: Value, newValue: Value) -> Bool {
        oldValue != newValue
    }

}

public class Observable<Value> {

    public init(wrappedValue: Value) {
        self.wrappedValue = wrappedValue
    }

    internal var observations = [Observation<Value>]() { didSet { isBeingObserved = !observations.isEmpty } }

    public var wrappedValue: Value {
        didSet {
            guard shouldExecuteNotifications(oldValue: oldValue, newValue: wrappedValue) else { return }
            observations.forEach {
                $0.executeNotification(oldValue: oldValue, newValue: wrappedValue)
            }
        }
    }

    public weak var delegate: ObservableDelegate?

    public var isBeingObserved = false {
        didSet {
            guard isBeingObserved != oldValue else { return }
            delegate?.isBeingObservedChanged(isBeingObserved)
        }
    }

    internal func shouldExecuteNotifications(oldValue: Value, newValue: Value) -> Bool { true }

}

Одна большая вещь - я заметил, что ошибка возникает только тогда, когда Я получаю доступ к этой переменной из другого файла, чем там, где она была определена. Я добавил геттеры и сеттеры на данный момент, но все еще не очень хорошее решение. Кажется, это ошибка компилятора, но я не уверен.

1 Ответ

0 голосов
/ 21 марта 2020

Использование оберток свойств в расширениях из другого файла, по-видимому, является причиной

того, что они утверждают в документации

Типы оберток свойств

A Тип оболочки свойства - это тип, который можно использовать в качестве оболочки свойства. Существует два основных c требования для типа оболочки свойства:

  1. Тип оболочки свойства должен быть определен с атрибутом @propertyWrapper. Атрибут указывает, что тип предназначен для использования в качестве типа оболочки свойства, и предоставляет точку, в которой компилятор может проверять любые другие правила согласованности.
  2. Тип оболочки свойства должен иметь свойство с именем wrappedValue, уровень доступа которого совпадает с уровнем доступа самого типа . Это свойство используется компилятором для доступа к базовому значению в экземпляре оболочки.
...