http://stackoverflow.com/questions/31515805/difference-between-computed-property-and-property-set-with-closure
The computed property’s block is called each time you reference the variable
Computed Property:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
var width = 100.0 var height = 100.0 // computing setter and getter var area: Double { get { return width * height } set(newArea) { let squareRootValue = sqrt(newArea) width = squareRootValue height = squareRootValue } } area // 10,000.0 area = 500 width // 22.36 height // 22.36 area = 100 width // 10.0 height // 10.0 area = 16 width // 4.0 height // 4.0 |
Stored Property
ASSUMING THAT YOU DO NOT set the stored property, the stored property’s initialization closure is called once and only once when you do the first READ. Any other READS after that will simply return the variable itself. Thus, it is useful for setting default values.
In other words, (granted you do not set it) it is calculated only when the variable is accessed for the first time. Then, it simply just returns the variable.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
class Test { // this will be called only 1 time if name is READ // when name is read 2nd...nth time, it will not run this function. // lazy var name : String = { print("-- load data for stored property 'name' --") var firstName : String = "Ricky" return firstName }() required init() { print("----init Test class-----") } deinit { print("destroy Test object") } } |
1 2 |
let temp = Test() temp.name // name here is Ricky. |
However, if you were to set the stored property, the initial closure will not be run, and it will simply access the variable
for you to use:
1 2 |
let temp = Test() temp.name = "GEORGE" // initialization closure never gets run for the stored property 'name' |
Now let’s test it. As you can see, if you READ the property name for the first time, the lazy load will be called. Every READ after that will be a direct access and it won’t call the function anymore.
1 2 3 4 5 |
let myTest = Test() print("\(myTest.name)") // calls the lazy closure print("\(myTest.name)") // simply accesses the name variable myTest.name = "Hannah" print("\(myTest.name)") // simply accesses the name variable |
output:
—-init Test class—–
— load data for stored property ‘name’ —
Ricky
Ricky
Hannah
Simply using SET will not call the closure
1 2 3 |
let myTest = Test() myTest.name = "Hannah" print("\(myTest.name)") // simply accesses the name variable |
When the property ‘name’ is set explicitly, it doesn’t do the lazy loading.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
lazy var sendBtn: UIButton = { var _sendBtn: UIButton = UIButton() _sendBtn.setTitle("Send", for: .normal) _sendBtn.setTitleColor( UIColor(red:0.00, green:0.46, blue:1.00, alpha:1.0), for: .normal) _sendBtn.frame = CGRect(x: gScreenSize.width - 66 - 10, y: (66 - 24)/2, width: 66, height: 24) _sendBtn.layer.masksToBounds = true _sendBtn.addTarget(self, action: #selector(saveClicked), for: .touchUpInside) return _sendBtn }() |