Properties In Swift

Stored Properties

Properties associate values with a particular class, structure, or enumeration. Stored properties store constant and variable values as part of an instance.
In its simplest form, a stored property is a constant or variable that is stored as part of an instance of a particular class or structure.

struct Size {
 var width: Int 
 let height: Int 
}
var size1 = Size(width: 10, height: 35)
size1.width = 6

In the example above, height is initialized when the new size is created. This is a constant property, and it cannot be changed once initialized.
When creating an instance of a structure, if you assign an instance of a structure to a constant, the instance‘s properties cannot be modified, even if they were declared as variable properties.

Lazy Stored Properties

A lazy stored property’s initial value is not calculated until the first time it is used.

class DataManager {
 lazy var importer = DataImporter()
 var data = [String]()
}

Lazy properties are useful when a property’s initial value is dependent on outside factors, the values of which are not known until after an instance‘s initialization is complete; or when the initial value for a property requires complex or computationally expensive setup that should not be performed unless or until it is needed.
You must always declare a lazy property as a variable, using the var keyword, because its initial value might not be retrieved until after the completion of instance initialization. Constant properties must always have a value before initialization completes, and therefore cannot be declared as lazy.

Computed Properties

Rather than storing a value, a computed property provides a getter and, optionally, a setter, which indirectly retrieve and set other properties and values, respectively.

struct Point {
 var x = 0.0, y = 0.0
}
struct Shape {
 var origin = Point() 
 var center: Point {
  get {
   return Point(x: origin.x/2 , y: origin.y/2)
  }
  set(newCenter) {
   origin.x = newCenter.x/2
   origin.y = newCenter.y/2
  }
 }
}

The Shape structure defines a custom getter and setter for a computed variable called center. The center property is then accessed through dot syntax, which causes the getter for center to be called to retrieve the current property value. Rather than returning an existing value, the getter actually calculates and returns a new point that represents the center of the shape.

If a computed property’s setter does not define a name for the new value to be set, a default name of newValue is used.
Below is an alternative version of the Rect structure, which takes advantage of this shorthand notation:

struct Point {
 var x = 0.0, y = 0.0
}
struct Shape {
 var origin = Point() 
 var center: Point {
  get {
   return Point(x: origin.x/2, y: origin.y/2)
  }
  set {
   origin.x = newValue.x/2
   origin.y = newValue.y/2
  }
 }
}

A computed property with a getter but no setter is known as a read-only computed property. It always returns a value, and can be accessed through dot syntax. However, that value cannot be altered.

Property Observers

Property observers detect and respond to changes in a property’s value. Property observers are called every time a property’s value is set, even if the new value is the same as the property’s current value.
Property observers can be added to any defined stored properties, with the exception of lazy stored properties.
You have the option of defining either or both of the following observers of a property:
willSet is called just before the value is stored.
didSet is called immediately after the new value is stored.

The example below defines a new class called StepCounter, which tracks the total number of steps that a person takes while walking.

class StepCounter {
 var totalSteps: Int = 0 {
  willSet(newSteps) {
   print("About to set totalSteps to \(newSteps)")
  }
  didSet {
   if totalSteps > oldValue  {
   print("Added \(totalSteps - oldValue) steps")
   }
  }
 }
}
let stepCounter = StepCounter()
stepCounter.totalSteps = 50
// About to set totalSteps to 50
// Added 50 steps
stepCounter.totalSteps = 150
// About to set totalSteps to 150
// Added 100 steps
stepCounter.totalSteps = 420
// About to set totalSteps to 420
// Added 270 steps

The StepCounter class declares a totalSteps property of type Int, with willSet and didSet observers.
The willSet and didSet observers for totalSteps are called whenever the property is assigned a new value.
The willSet observer uses a custom parameter name of newSteps for the upcoming new value.

The didSet observer is called after the value of totalSteps is updated. It compares the new value of totalSteps against the old value. The didSet observer does not provide a custom parameter name for the old value; the default name of oldValue is used, instead.
Similarly, newValue could be used for the willSet observer, if no parameter name was defined.
If you assign a value to a property within its own didSet observer, the new assigned value will replace the one that was just set.

Type Properties

Type properties are useful when defining values that are universal to all instances of a particular type, such as a constant property used in all instances, or a variable property that stores a global value to all instances of that type. Stored type properties can be variables or constants. You define type properties with the static keyword:

class SomeClass {
 static var storedProp = "Some value."
 static var computedProp: Int {
   return 42
 }
}

Type properties are queried and set with dot syntax, just like instance properties. However, type properties are queried and set on the type, not on an instance of that type:

print(SomeClass.storedProp) 

Unlike stored instance properties, you must always give stored type properties a default value. This is because the type itself does not have an initializer that can assign a value to a stored type property at initialization time.

Advertisements
Properties In Swift

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s