-
Notifications
You must be signed in to change notification settings - Fork 3
Overview_Properties
Tom Ryan edited this page Jun 3, 2015
·
1 revision
There are several ways of providing custom behavior when getting or setting a property.
didSet
executes additional operations after the property has been set.
struct MyDidSetStruct {
var firstname : String
var lastname : String? {
didSet {
println("Setting job description")
self.jobDescription = "\(self.lastname!) has a job description"
}
}
var jobDescription : String?
init(firstname: String) {
self.firstname = firstname
}
}
var describedPerson = MyDidSetStruct(firstname: "Fred")
describedPerson.lastname = "Baxter"
describedPerson.jobDescription //"Baxter has a job description"
willSet
executes operations before the property has been set.
struct MyWillSetStruct {
var firstname : String
var lastname : String? {
willSet {
self.lastname = "\(newValue) is a dork"
}
}
var jobDescription : String?
init(firstname: String) {
self.firstname = firstname
}
}
var describedPerson = MyWillSetStruct(firstname: "Fred")
describedPerson.lastname = "Baxter"
describedPerson.lastname! // "Baxter is a dork"
struct MyLazyStruct {
let firstname: String
let lastname: String?
lazy var fullname : String = {
return "\(self.firstname) \(self.lastname!)"
}()
}
Note that the above code is unsafe because it's unwrapping an optional (
self.lastname!
). This will crash at runtime ifself.lastname
is nil.
At times, it makes sense to fully override get
and set
. This can be useful when for example, the property will be loaded and saved as an NSUserDefault
.
In this case, create a private var to store the value, and a public var for the additional operations.
Note: Fully custom
get
andset
is much less preferable than leveragingdidSet
orwillSet
.
class MyUserController {
private var _porpoise : Porpoise?
var porpoise : Porpoise {
get {
if let user = self._porpoise {
return user
} else if let user = Porpoise.load() {
return user
} else {
return Porpoise()
}
}
set {
self._porpoise = newValue
Porpoise.save(self._porpoise!)
}
}
init() {
self._porpoise = Porpoise.load()
}
struct Porpoise {
var firstname: String!
static func load() -> Porpoise? {
if let data = NSUserDefaults.standardUserDefaults().objectForKey("SavedUser") as! NSData?, dict = NSJSONSerialization.JSONObjectWithData(data, options: NSJSONReadingOptions.AllowFragments, error: nil) as? [String : AnyObject] {
var firstname = dict["firstname"] as! String
var person = Porpoise(firstname: firstname)
return person
} else {
var porpoise = Porpoise()
porpoise.firstname = "Unknown"
return porpoise
}
}
static func save(user: Porpoise) {
//no-op for the purposes of this demo.
}
}
}