Swift: The rules of being weak (Xcode 6 Beta 7)


The weak keyword is one measure used in Swift to prevent strong reference cycles occurring. These strong reference cycles happen when two instances point at one another and ARC (automatic reference counting) cannot perform the required releases. Or as Apple describes the situation, 'two class instances hold a strong reference to each other, such that each instance keeps the other alive'.

Rules of the weak keyword

Here are the rules of the weak keyword
  1. it can be used inside classes, structs, enums and protocols
  2. it can only be used with variables and properties
  3. the variables and properties it is used with must be optionals
  4. it cannot be used to declare (or set) variables that are non-class types, for example weak var a:String? would raise a compiler error (as will all of Swift's own types, since they are all structs and enums)
And while it might be an obvious point, a weak reference must be paired with a regular (strong) reference to be of practical use. This, for instance, would be a pointless assignment on its own:
weak var a:Person? = Person(name: "John Appleseed") // nil
 
The reason being that as soon as the assignment is made it is released and the value is set to nil.

Example of using weak

These rules restrict the use of the weak keyword to use as described by Apple in the examples to be found here. Or to when doing something like this:
// place class on its own
class Person {
    let name: String
    init(name: String) { self.name = name }
      deinit {
        println("\(name) is being deinitialized")
    }
}

// place in body of your struct or class 
weak var a:Person?
var b:Person?
 
// place inside a method 
b = Person(name: "john")
a = b
b = nil // deinitialization happens here, doesn't wait for a to become nil since it is a weak reference 

Tips for testing weak

A couple of tips for testing the deintiliazation:
  1. you must use the Simulator, not a Playground, in order to see the deinitialization taking place
  2. even with strong references, ARC deinitializes as soon as possible, which means that if you place the variable declarations in the same method as the assignments then once that method has ended the instances will be released and deinitialized anyway without even setting the strong reference to nil
Note: discussion of the use of the unowned keyword can be found in this post and discussion of the use of weak (and unowned) in closures will follow in a later post.

Endorse on Coderwall

Comments