Swift 中的数据封装和安全性

Data encapsulation and security in Swift

我目前正在 Swift 学习 iOS 开发,并且遇到了数据封装和安全性的概念。让我们从一个例子开始:

Class Person {
    private var _weight: Int!

    var weight: Int {
        get {
            return _weight
        }
        set {
            _weight = newValue
        }
    }
}

在教程中,我被教导为了安全起见总是创建一个私有变量,这样变量就不会在外部超出范围并改变数据。而且导师还强调要像上面那样显式设置getter和setter。写 getter 和 setter 对我来说似乎很麻烦,似乎我只需要在需要时使用 getter 和 setter 。 (即 getter 可用于只读 属性 并且 setter 可用于计算 属性 的目的)。

我想知道我是否需要一直遵循这种做法,或者我是否可以像下面这样简单地定义 属性:

Class Person {
    var _weight: Int!
}

你的教授是正确的,但对于 swift 在我看来你不需要添加 _ 到你的变量来强调它们是私有的,因为我们已经有了“私有 ” opt in swift。_ 适用于像 python 这样的语言,你不能为你的变量和函数设置特定的标识符,比如 private 。此外,你不需要编写 getter 和 setter,如果你没有操纵它,或者如果它上面没有特定的 condition/implication。像你下面的例子一样定义它就可以了

在 Swift 中,您无需为所有属性显式声明 getter 和 setter,除非您想自定义它们的行为。

大多数时候,这会工作得很好:

class Person {
    var weight: Int
}

您甚至可以将变量设置为公开只读,私有读写:

class Person {
    public private(set) var weight: Int
}

当您想要自定义 getter 和 setter 的行为时,您的讲师示例很有用,例如从某些外部源延迟获取数据:

class Person {
    private var _weight: Int!

    var weight: Int {
        get {
            if _weight == nil {
                //fetch _weight from somewhere
            }
            return _weight!
        }
        set {
            _weight = newValue
        }
    }
}

Private variables are not a security feature。转储对象的内存并从中提取私有变量是微不足道的,在许多语言中,您可以使用反射等功能更轻松地访问它们。

而是私有变量是为了封装。标记为 private 的变量意味着 "This is an internal interface so do not use it. If you do use it, it's not guaranteed to work, and even if it works now, it might not work in the future." 私有变量还可以允许编译器在某些情况下执行一些额外的优化,因为它知道除了这个 class 之外的任何地方都不会访问该变量宣言.