I am taking the CS193 class. From this exact moment of the video.
Option 1:
class FaceView: UIView
{
var scale: CGFloat = 0.90
var mouthCurvature: Double = 1.0
private var skullRadius: CGFloat {
return min(bounds.size.width, bounds.size.height) / 2 * scale
}
}
Why can't I write
Option 2:
class FaceView: UIView
{
var scale: CGFloat = 0.90
var mouthCurvature: Double = 1.0
private var skullRadius = min(bounds.size.width, bounds.size.height) / 2 * scale
}
The professor goes and explains that you during initialization you can't access your own property and therefore if you do option 2, you will get an error saying: instance member 'bounds' cannot be used on type 'FaceView'
.
OK, but aren't we still accessing the instance member 'bounds` in Option 1 as well? What's the difference? Or is it that accessing is OK, but you can't make one property dependent on another during initialization?
This is one of the differences between stored properties and computed properties.
The stored properties scale
and mouthCurvature
are initialized when an instance of FaceView
is instantiated.
In your first example skullRadius
is a computed property which is computed when your FaceView
instance has that property called upon, after instantiation.
In the second example skullRadius
is a stored property which is initialized at instantiation. The other properties are not yet available at that point because they may or may not be initialized.
Here's how you can refer to another property during initialization:
class test {
let foo = 1 // stored property
let bar = 2 // stored property
let buzz: Int // stored property not initialized when other stored properties are initialized
init() {
buzz = foo + bar // initialized after other stored properties
}
}
Example showing how lazy properties can be modified:
class Test {
lazy var foo: Int = { return 5 }()
}
let test = Test()
print(test.foo) -> "5"
test.foo = 10
print(test.foo) -> "10"