Thursday, January 18, 2018

Explain what Lazy stored properties is and when it is useful?

A lazy stored property is a property whose initial value is not calculated until the first time it is used. You indicate a lazy stored property by writing the lazy modifier before its declaration.

NOTE
You must always declare a lazy property as a variable (with the var keyword), because its initial value might not be retrieved until after instance initialization completes. Constant properties must always have a value before initialization completes, and therefore cannot be declared as lazy.

Lazy properties are useful when the initial value for a property is dependent on outside factors whose values are not known until after an instance’s initialization is complete. Lazy properties are also useful when the initial value for a property requires complex or computationally expensive setup that should not be performed unless or until it is needed.

The example below uses a lazy stored property to avoid unnecessary initialization of a complex class. This example defines two classes called DataImporter and DataManager, neither of which is shown in full:

  1. class DataImporter {
  2. /*
  3. DataImporter is a class to import data from an external file.
  4. The class is assumed to take a nontrivial amount of time to initialize.
  5. */
  6. var filename = "data.txt"
  7. // the DataImporter class would provide data importing functionality here
  8. }
  9. class DataManager {
  10. lazy var importer = DataImporter()
  11. var data = [String]()
  12. // the DataManager class would provide data management functionality here
  13. }
  14. let manager = DataManager()
  15. manager.data.append("Some data")
  16. manager.data.append("Some more data")
  17. // the DataImporter instance for the importer property has not yet been created

The DataManager class has a stored property called data, which is initialized with a new, empty array of String values. Although the rest of its functionality is not shown, the purpose of this DataManager class is to manage and provide access to this array of String data.

Part of the functionality of the DataManager class is the ability to import data from a file. This functionality is provided by the DataImporter class, which is assumed to take a nontrivial amount of time to initialize. This might be because a DataImporter instance needs to open a file and read its contents into memory when the DataImporter instance is initialized.

It is possible for a DataManager instance to manage its data without ever importing data from a file, so there is no need to create a new DataImporter instance when the DataManager itself is created. Instead, it makes more sense to create the DataImporter instance if and when it is first used.

Because it is marked with the lazy modifier, the DataImporter instance for the importer property is only created when the importer property is first accessed, such as when its filename property is queried:

  1. print(manager.importer.filename)
  2. // the DataImporter instance for the importer property has now been created
  3. // Prints "data.txt"


NOTE
If a property marked with the lazy modifier is accessed by multiple threads simultaneously and the property has not yet been initialized, there is no guarantee that the property will be initialized only once.