6

これで、遅延変数を作成する新しい方法ができました。これは、swift-evolution/proposals/0258-property-wrappers.mdで説明されています。

@propertyWrapper
enum Lazy<Value> {
    case uninitialized(() -> Value)
    case initialized(Value)

    init(wrappedValue: @autoclosure @escaping () -> Value) {
        self = .uninitialized(wrappedValue)
    }

    var wrappedValue: Value {
        mutating get {
            switch self {
            case .uninitialized(let initializer):
                let value = initializer()
                self = .initialized(value)
                return value
            case .initialized(let value):
                return value
            }
        }
        set {
            self = .initialized(newValue)
        }
    }
}

スレッドセーフな実装ですか? そうでない場合、非スレッドセーフな動作を再現する方法は?

4

1 に答える 1

3

同じ質問があったので、クラスのプロパティでこのプロパティ ラッパーを使用する小さなテストを作成してテストし、値 (エポックからの時間) を非同期 (10000 回) に出力しようとしたところ、失敗しました。ラップされた値のゲッター内の「戻り値」行にSIGABRTを使用します。

また、印刷せずに値を「取得」しようとしましたが、同じ問題がありました。

だから私は言わなければならないでしょう:いいえ、それはスレッドセーフではありません。

編集: https://www.onswiftwings.com/posts/atomic-property-wrapper/で同じテストを行ったことを追加したいと思います。これは実際にスレッドセーフであるため、それをベースとして使用できますスレッドセーフな独自の「Lazy」を作成します。

于 2019-11-18T11:26:51.030 に答える