加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Swift中的Getter和Setter – 使用WillSet和DidSet是否有意义?

发布时间:2020-12-14 05:30:21 所属栏目:百科 来源:网络整理
导读:我正在研究我们应该为我们的属性使用Get和Set的原因. 我注意到了3个主要原因 如果你想在实际设置之前做/检查一些事情 属性 如果您想拥有一个只能从中获取的属性 (可能出于安全考虑,我猜?),或给它不同的访问权限 水平. 在暴露a时隐藏属性的内部表示 使用替代
我正在研究我们应该为我们的属性使用Get和Set的原因.

我注意到了3个主要原因

>如果你想在实际设置之前做/检查一些事情
属性
>如果您想拥有一个只能从中获取的属性
(可能出于安全考虑,我猜?),或给它不同的访问权限
水平.
>在暴露a时隐藏属性的内部表示
使用替代表示的财产. (对我来说没有
因为我可以使用在错误的地方访问它,所以很有意义
无论如何都要设置功能)

下面的代码是一个如何在Swift中实现Get和Set属性的示例,利用我提到的3点:

class Test
{
    private var _testSet:String!
    private var _testGetOnly:String
    var testSet:String{
        get{
            return _testSet
        }
        set{
            _testSet = newValue + "you forgot this string"
        }
    }
    var testGetOnly:String!{
        get{
            return _testGetOnly
        }
    }

    init(testSet:String,testGetOnly:String)
    {
        _testSet = testSet
        _testGetOnly = testGetOnly
    }
}

但是下面的另一个例子也利用了提到的那些点,而不是使用另一个计算属性来返回私有属性值我只使用了willSet和didSet观察者

class Test
{
    var testGet:String {
        willSet{
            fatalError("Operation not allowed")
        }
    }
    var testWillSet:String!{
        didSet{
            self.testWillSet = self.testWillSet + "you forgot this string"
        }
    }
    init(testGet:String,testWillSet:String)
    {
        self.testGet = testGet
        self.testWillSet = testWillSet 
    }
}

所以我很想知道每个实现的优点和缺点是什么.

提前致谢

您的问题归结为编译时间与运行时错误.解决您的3个问题:

>是的,willCheck是您唯一的选择
>只读属性分为两种类型:(a)其值来自其他属性的那些,例如,它们的总和; (b)您希望能够自行更改但不能由用户更改的内容.第一种类型真的没有二传;第二种类型有一个公共吸气剂和一个私人二传手.编译器可以帮助您检查它,程序将无法编译.如果在didSet中抛出fatalError,则会出现运行时错误,应用程序将崩溃.
>可能存在您不希望用户自由处理的状态对象,是的,您可以完全隐藏用户的状态.

您的代码第一个示例在定义支持变量时过于冗长 – 您不需要这样做.为了说明这些要点:

class Test
{
    // 1. Validate the new value
    var mustBeginWithA: String = "A word" {
        willSet {
            if !newValue.hasPrefix("A") {
                fatalError("This property must begin with the letter A")
            }
        }
    }

    // 2. A readonly property
    var x: Int = 1
    var y: Int = 2
    var total: Int {
        get { return x + y }
    }

    private(set) var greeting: String = "Hello world"
    func changeGreeting() {
        self.greeting = "Goodbye world" // Even for private property,you may still
                                        // want to set it,just not allowing the user
                                        // to do so
    }

    // 3. Hide implementation detail
    private var person = ["firstName": "","lastName": ""]
    var firstName: String {
        get { return person["firstName"]! }
        set { person["firstName"] = newValue }
    }

    var lastName: String {
        get { return person["lastName"]! }
        set { person["lastName"] = newValue }
    }

    var fullName: String {
        get { return self.firstName + " " + self.lastName }
        set {
            let components = newValue.componentsSeparatedByString(" ")
            self.firstName = components[0]
            self.lastName = components[1]
        }
    }
}

用法:

let t = Test()
t.mustBeginWithA = "Bee"        // runtime error

t.total = 30                    // Won't compile

t.greeting = "Goodbye world"    // Won't compile. The compiler does the check for you
                                // instead of a crash at run time

t.changeGreeting()              // OK,greeting now changed to "Goodbye world"

t.firstName = "John"            // Users have no idea that they are actually changing 
t.lastName = "Smith"            // a key in the dictionary and there's no way for them
                                // to access that dictionary

t.fullName = "Bart Simpsons"    // You do not want the user to change the full name
                                // without making a corresponding change in the
                                // firstName and lastName. With a custome setter,you
                                // can update both firstName and lastName to maintain
                                // consistency

关于Swift 2与Swift 3中的私密性的说明:如果你在Swift 2游乐场试试这个,你会发现t.greeting =“Goodbye world”的效果很好.这是因为Swift 2有一个奇怪的访问级别说明符:private表示“只能在当前文件中访问”.将类定义和示例代码分成不同的文件,Xcode会抱怨.在Swift 3中,它被更改为fileprivate,它更清晰,并保存private关键字,以便更类似于Java和.NET

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读