在 Swift 5.1 属性 包装器中访问自身

Access self in Swift 5.1 Property Wrappers

我想创建一个 属性 包装器,它会使我的 UICollectionViewLayout 布局无效。

因此我创建了这个 属性 包装器

@propertyWrapper
class LayoutInvalidating {
    private let layout: UICollectionViewLayout

    init(layout: UICollectionViewLayout) {
        self.layout = layout
        self.wrappedValue = layout
    }

    var wrappedValue: UICollectionViewLayout {
        didSet {
            self.layout.invalidateLayout()
        }
    }
}

那我想这样用

final class VehicleControlsCollectionViewLayout: UICollectionViewLayout {
     @LayoutInvalidating(layout: self) // self is not alive
     public var itemSize: CGSize = .init(width: 70, height: 70)
}

每次设置 属性 时,我都想调用 self.invalidateLayout()。有什么想法可以在 self 存在时访问它吗?

不幸的是,无法将 self 添加到 @propertyWrapper init - 这个 属性 是在创建 self 的过程中创建的。

将来可能 - 查看 proposal在包装类型中引用封闭的 'self')。


如果您正在寻找某种 解决方法,您可以考虑向 属性 包装器添加函数,并在 class 中初始化后调用此函数]:

@propertyWrapper
class LayoutInvalidating<Value> {
    private var layout: UICollectionViewLayout?

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

    func configure(with layout: UICollectionViewLayout?) {
        self.layout = layout
    }

    var wrappedValue: Value {
        didSet {
            layout?.invalidateLayout()
        }
    }
}

final class VehicleControlsCollectionViewLayout: UICollectionViewLayout {
    @LayoutInvalidating
    public var itemSize: CGSize = .init(width: 70, height: 70)

    override init() {
        super.init()
        _itemSize.configure(with: self)
    }
}