Understanding property observers

Each superhero has a running speed score that determines how fast he will move when running; therefore, we will add a public runningSpeedScore property. We will change the initializer code to set an initial value for the new property. However, this new property has some specific requirements.

Whenever the running speed score is about to change, it will be necessary to trigger a few actions. In addition, we have to trigger other actions after the value for this property changes. We might consider adding code to a setter method combined with a related property, run code before we set the new value to the related property, and then run code after we set the new value. However, Swift allows us to take advantage of property observers that make it easier to run the code before and after the running speed score changes.

We can define a public runningSpeedScore property with both a willSet and didSet methods. After we create an instance of the new version of the SuperHero class and initialize the new property with its initial value, the code in the willSet method will be executed when we assign a new value to the property and before Swift sets the new value to the property. Thus, at the time the willSet method executes the code, the property still has the previous value, and we can access the new value that will be set by checking the value of the newValue implicit parameter.

Then, when Swift changes the value of the property, the didSet method will be executed. Thus, at the time the didSet method executes the code, the property has the new value.

Tip

The code defined in the willSet and/or didSet methods only runs when we change the value of the property after its initial value is set. Thus, property observers don't run when the property is initialized.

The following lines show the code that defines the new public runningSpeedScore property with the property observers and the new code for the initializer. Note that the code for the rest of the class isn't included in order to avoid repeating the previous code. The code file for the sample is included in the swift_3_oop_chapter_03_09 folder:

    public var runningSpeedScore: Int { 
      willSet { 
        print("The current value for running speed score 
        is:(runningSpeedScore)") 
        print("I will set the new value for running speed 
        score to: (newValue)") 
      } 
      didSet { 
        print("I have set the new value for running speed 
        score to: (runningSpeedScore)") 
      } 
    } 
     
    init(name: String, birthYear: Int, sneakers: String, 
    runningSpeedScore: Int) { 
      self.name = name 
      self.birthYear = birthYear 
      self.runningSpeedScore = runningSpeedScore 
      self.sneakers = sneakers 
    } 
   

The willSet method prints the current value of runningSpeedScore and the new value that will be set to this property and received in the newValue implicit parameter. The didSet method prints the new value that is set to the runningSpeedScore property.

Tip

Swift makes it easy to insert the value of an expression into a string by placing the expression within parentheses after a backslash (). We took advantage of this syntax in the previous code to print the values of both runningSpeedScore and newValue as part of a message string.

The initializer for the class added a new argument that provides an initial value to the new runningSpeedScore property. The next lines create an instance of the SuperHero class and assign a value to the runningSpeedScore property. Note that both the willSet and didSet methods were executed only once because the code didn't run when we initialized the value of the property. Enter the lines after the code that creates the new version of the SuperHero class. The code file for the sample is included in the swift_3_oop_chapter_03_09 folder:

    var superBoy = SuperHero(name: "Super-Boy", birthYear: 
    2008, sneakers: "Running with Swift 3", 
    runningSpeedScore: 5) 
    print(superBoy.sneakers) 
    superBoy.runningSpeedScore = 7 

The Playground displays a message indicating the current value of the property before the new value that is set, that will be set, and finally, that was set, as shown in the next screenshot:

Understanding property observers

Tip

When we take advantage of property observers, we cannot use getters and/or setters at the same time. Thus, we cannot define getter and/or setter methods when we use the willSet and/or didSet methods for a property. Swift doesn't make it possible to combine them.

We can use the didSet method to keep the value of a property in a valid range. For example, we can define the runningSpeedScore property with a didSet method, which transforms the values lower than 0 to 0 and values higher than 50 to 50. The following code will do the job. We have to replace the previous code, which declared the runningSpeedScore property, with the new code. The code file for the sample is included in the swift_3_oop_chapter_03_10 folder:

    public var runningSpeedScore: Int { 
      didSet { 
        if (runningSpeedScore < 0) { 
          runningSpeedScore = 0 
        } 
        else if (runningSpeedScore > 50) { 
          runningSpeedScore = 50 
        } 
      } 
    } 

The next lines create an instance of the SuperHero class and try to assign different values to the runningSpeedScore property. Enter the lines after the code that creates the new version of the SuperHero class:

    var superBoy = SuperHero(name: "Super-Boy", birthYear: 
    2008, sneakers: "Running with Swift 3", 
    runningSpeedScore: 5) 
    print(superBoy.runningSpeedScore) 
    superBoy.runningSpeedScore = -5 
    print(superBoy.runningSpeedScore) 
    superBoy.runningSpeedScore = 200 
    print(superBoy.runningSpeedScore) 
    superBoy.runningSpeedScore = 6 
    print(superBoy.runningSpeedScore) 

After we specified -5 as the desired value of the runningSpeedScore property, we printed its actual value, and the result was 0. After we specified 200, the actual printed value was 50. Finally, after we specified 6, the actual printed value was 6, as shown in the next screenshot. The code in the didSet method did its job; we can control all the values accepted for the property. Note that the didSet method doesn't execute one more time when we set the new value for the property within the didSet method. The code file for the sample is included in the swift_3_oop_chapter_03_10 folder:

Understanding property observers

We can use the didSet method when we want to validate the values accepted for a property after it is initialized. Remember that the didSet method isn't executed when the property is initialized. Thus, if we execute the following lines, the printed value will be 135, and the property will be initialized with an invalid value. Enter the lines after the code that creates the new version of the SuperHero class. The code file for the sample is included in the swift_3_oop_chapter_03_11 folder:

    var superFlash = SuperHero(name: "Flash", 
    birthYear: 1972, sneakers: "Flash running", 
    runningSpeedScore: 135) 
    print(superFlash.runningSpeedScore) 
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.15.229.161