0

属性观察者和属性包装器之间的主要区别是什么?它们似乎非常相似,因为它们管理属性的存储方式。我唯一能想到的是您可以重用属性包装器,因为在管理属性存储方式的代码和定义属性的代码之间存在一层分离。

属性包装器

@propertyWrapper
struct TwelveOrLess {
    private var number: Int
    init() { self.number = 0 }
    var wrappedValue: Int {
        get { return number }
        set { number = min(newValue, 12) }
    }
}

struct Rectangle {
    @TwelveOrLess var height: Int
    @TwelveOrLess var width: Int
}

物业观察员

struct Rectangle {
    var height: Int {
        didSet {
            if oldValue > 12 {
                height = 12
            } else {
                height = oldValue
            }
        }
    }

    var width: Int {
        didSet {
            if oldValue > 12 {
                width = 12
            } else {
                width = oldValue
            }
        }
    }
}

上面两种情况几乎完成了相同的事情,就是将属性设置为等于或小于 12。

4

2 回答 2

1

属性观察者和属性包装器之间的另一个重大区别是属性观察器可以访问self,而属性包装器还不能(在撰写本文时)self使用稳定的、记录在案的接口进行访问。

您可以通过selfinit. 属性包装器提案中描述了此解决方法。

您可以self使用未记录的、不稳定的界面在属性包装器中访问,您可以通过在您最喜欢的搜索引擎中输入“property wrapper _enclosureInstance”来了解它。

于 2020-06-16T22:10:40.320 回答
1

你说:

我唯一能想到的是您可以重用属性包装器,因为在管理属性存储方式的代码和定义属性的代码之间存在一层分离。

您的示例(以及您的一些文本)似乎来自Swift Programming Language: Property Wrapper手册:

属性包装器在管理属性存储方式的代码和定义属性的代码之间添加了一层分隔。例如,如果您有提供线程安全检查的属性或将其基础数据存储在数据库中,则必须在每个属性上编写该代码。使用属性包装器时,您在定义包装器时编写一次管理代码,然后通过将其应用于多个属性来重用该管理代码。

所以,是的,属性包装器的优点是通过分离“管理如何存储属性的代码和定义属性的代码”来实现重用。这种重用是属性包装器的全部内容。

很明显,您也可以编写自己的 setter 和 getter(恕我直言,这比编写自身变异的观察者的模式更好),但是您失去了属性包装器提供的重用和抽象。

你接着说:

上面两种情况几乎完成了相同的事情,就是将属性设置为等于或小于 12。

当然可以,但是如果您想为十个不同的属性执行此操作,包装器可以避免您需要重复此代码十次。它还将这个“等于或小于 12”逻辑的细节从你声明属性的地方抽象出来。

于 2020-06-16T22:01:47.187 回答