Types of Swift Properties

By Jesse Feiler

In Swift, backing variables are explicitly declared if needed (usually in code converted from Objective‐C). Also, getters need not use the get keyword. Swift properties can be variables or constants; each type can be either stored or computed, as follows:

  • Declaring a variable property: A variable is introduced with the keyword var as in:

    var _fetchedResultsController:
        NSFetchedResultsController? = nil
  • Declaring a constant property: A constant (that is, a property that cannot be modified) is introduced with the keyword let. The previous declaration can be changed to declare a constant as follows:

    let _fetchedResultsController:
        NSFetchedResultsController? = nil
  • Declaring a stored property: The declaration of _fetchedResultsController shown in the following listing is a typical declaration of a stored property. A stored property is a property stored as part of an instance of the class, enumeration, or structure.

    // MARK: - Fetched results controller
      var fetchedResultsController: NSFetchedResultsController
        {
        if _fetchedResultsController != nil {
          return _fetchedResultsController!
        }
        let fetchRequest = NSFetchRequest()
        // Edit the entity name as appropriate.
        let entity =
          NSEntityDescription.entityForName("Event",
          inManagedObjectContext: self.managedObjectContext!)
          fetchRequest.entity = entity
        // Set the batch size to a suitable number.
        fetchRequest.fetchBatchSize = 20
        // Edit the sort key as appropriate.
        let sortDescriptor = NSSortDescriptor(key:
          "timeStamp", ascending: false)
        let sortDescriptors = [sortDescriptor]
        fetchRequest.sortDescriptors = [sortDescriptor]
        // Edit the section name key path and cache name if appropriate.
        // nil for section name key path means "no sections".
        let aFetchedResultsController =
          NSFetchedResultsController(fetchRequest:
            fetchRequest,
          managedObjectContext: self.managedObjectContext!,
          sectionNameKeyPath: nil, cacheName: "Master")
        aFetchedResultsController.delegate = self
        _fetchedResultsController = aFetchedResultsController
        var error: NSError? = nil
        if !_fetchedResultsController!.performFetch(&error) {
          // Replace this implementation with code to handle
          // the error appropriately.
          // abort() causes the application to generate a
          // crash log and terminate. You should not use this
          // function in a shipping application, although it
          // may be useful during development.
          println("Unresolved error (error),
            (error.userInfo)")
          abort()
        }
        return _fetchedResultsController!
      }
      var _fetchedResultsController:
        NSFetchedResultsController? = nilBy default, the variable passed into the setter is named newValue, 
    and Swift uses the appropriate type for it.

    The example uses an Objective‐C pattern for a backing variable: Swift stored properties don’t need to begin with a special character such as an underscore; however, they do need to be initialized and given a type (perhaps inferred from the initialization) before they are used.

    var _fetchedResultsController:
      NSFetchedResultsController? = nil
  • Declaring a computed property with a getter and a setter: This point deserves a bit of elucidation. The listing shows a basic getter and setter of a Swift property. You can see that myVar has a backing variable of myInt. The get and set keywords identify the getter and setter.

    var myInt:Int = 0
    var myVar: Int {
      get {
        return myInt
      }
      set {
        myInt = newValue
      }
    }
    myVar = 20

    This is how you create a computed property.

In addition to the getters and setters shown in the following figure, you can use observers as shown in the next listing. This code is in the DetailViewController.swift file of Locatapp (from the Master‐Detail Application template).

image0.jpg

var detailItem: AnyObject? {
  didSet {
    // Update the view.
    self.configureView()
  }
}Set a breakpoint in this method and run the app in iOS Simulator. The button causes the method to be called.

This is a good place to call a view updater (which is exactly what is done in the template). There are two observers you can use:

  • didSet: This is called after the fact.

  • willSet: This is called just before the setting happens.