Hen*_*sta 8 oop get set swift computed-properties
我正在研究我们应该为我们的属性使用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
}
}
Run Code Online (Sandbox Code Playgroud)
但是下面的另一个例子也利用了提到的那些点,但是不使用另一个计算属性来返回私有属性值,我只使用了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
}
}
Run Code Online (Sandbox Code Playgroud)
所以我很想知道每个实现的优点和缺点是什么.
提前致谢
您的问题归结为编译时间与运行时错误。解决你的3个问题:
willCheck这是你唯一的选择fatalError运行didSet时错误,你的应用程序将会崩溃。您的代码第一个示例在定义支持变量方面过于冗长 - 您不需要这样做。为了说明以下几点:
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]
}
}
}
Run Code Online (Sandbox Code Playgroud)
用法:
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
Run Code Online (Sandbox Code Playgroud)
关于 Swift 2 与 Swift 3 的注释private:如果您在 Swift 2 Playground 中尝试此操作,您会发现t.greeting = "Goodbye world"效果很好。这是因为 Swift 2 有一个奇怪的访问级别说明符:private意味着“只能在当前文件内访问”。将类定义和示例代码分离到不同的文件中,Xcode 会报错。在 Swift 3 中,这一点已更改为fileprivate更清晰,并且保存了private与 Java 和 .NET 更相似的关键字
| 归档时间: |
|
| 查看次数: |
1900 次 |
| 最近记录: |