Swift中的Getter和Setter – 使用WillSet和DidSet是否有意义?
我正在研究我们应该为我们的属性使用Get和Set的原因.
我注意到了3个主要原因 >如果你想在实际设置之前做/检查一些事情 下面的代码是一个如何在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是您唯一的选择 您的代码第一个示例在定义支持变量时过于冗长 – 您不需要这样做.为了说明这些要点: 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 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |