All sample code in this chapter should be executed in an iOS/Mac Xcode project instead of Playground. Playground will hold all variables in it, so you might be unable to obtain correct results.

Memory management plays a critical role in all programming languages, so I have a plan to say about it more than other tips. But take easy, it will not be a full-length novel. :)

As Apple introduced, Swift will manage the memory automatically. When we create an object using initializers, Swift will alloc needed memory for us. And the dealloc will happen following the rule of Automatic Reference Counting (ARC). The core concept of ARC is fairly simple. Once there is no strong reference to an object (reference count to 0), that object will get deinit and its memory will be collected. This mechanism simplifies coding: the only thing to consider is when the reference be invalid (either beyond the scope or set to nil manually).

However, there is an obstacle all languages using ARC can not bybass - retain cycle.

What is Retain Cycle

Although I wonder if the concept introduction of retain cycle should be existing in this book or not (it is not a beginner book), I explain it again to describe the situation clearer in Swift. Think we have two classes A and B, and both of them has a property holding each other:

class A {
    let b: B
    init() {
        b = B()
        b.a = self
    }

    deinit {
        print("A deinit")
    }
}

class B {
    var a: A? = nil
    deinit {
        print("B deinit")
    }
}

In the init method of A, we make an instance of B and set it to the b property. Later we assign the instance of A to b.a. Here a.b and b.a forms a retain cycle.

Now when we create an instance with A(), then set it to nil immediately, deinit() of A and B will never get called, since there is always a reference between each other:

func application(application: UIApplication!,
                 didFinishLaunchingWithOptions launchOptions: NSDictionary!)
                 -> Bool
{

    // Override point for customization after application launch.

    var obj: A? = A()
    obj = nil
    // No release. Leaked.

    return true
}

There is no way to release obj and obj.b after the obj set to nil due to we can not get the reference of it anywhere. It will remain in memory forever unless kill the whole process, what a sad story..:(

Prevent retain cycle in Swift

We must give our clever compiler a hint that we do not hope they hold each other to work around this. Change the definition of class B to:

class B {
    weak var a: A? = nil
    deinit {
        print("B deinit")
    }
}

Here we add a weak before var a. It tells the compiler that a should not be held. ARC mechanism will not add reference counting for a weak reference. After adding weak, when obj is set to nil, there is no strong reference to the instance of A in the program, so obj could be released. As the releasing of obj, obj.b is out of scope as well, which leads to a 0-reference to b as well. The output would be:

A deinit
B deinit

There is another keyword indicating "do not strong reference me", yeah, it's unowned. If you are familiar with old time Objective-C, I would say unowned has some similar points as unsafe_unretained, while weak in Swift is the same thing as weak in Objective-C. unowned reference will keep to "point" to the original memory, even it is already not pointed by any strong reference and get deinited. If you try to access this invalid memory, your app will crash. While weak is a bit friendly, when reference content deinited, variable marked as weak will change to nil (so all weak variable must be an Optional value). How to choose which one to use? A good suggestion would be: if you are sure the instance will not be released during access, use unowned; otherwise, use weak.

Let's take some examples. The most important situations to use a weak reference are:

  1. When you set a delegate. The delegate property should not hold the referred content.
  2. Store a closure containing access to self to a property in self.

The first one is a very common pattern in Cocoa programming. Say that we have a class be responsible for asynchrony network request. It sends a request and receives the response. There is a protocol to inform the caller that a request is finished and it can do something with the response. At this time, we always set the delegate to weak, to not hold the caller incorrectly:

// RequestManager.swift
class RequestManager: RequestHandler {

    func requestFinished() {
        print("Requst finished")
    }

    func sendRequest() {
        let req = Request()
        req.delegate = self

        req.send()
    }
}

// Request.swift
@objc protocol RequestHandler {
    optional func requestFinished()
}

class Request {
    weak var delegate: RequestHandler!;

    func send() {
        // Send request async
        // The network framework will hold req object.
    }

    func gotResponse() {
        // Response
        // If anyone is interested in the response, invoke it.
        delegate?.requestFinished?()
    }
}

req is holding a weak reference to the instance of RequestManager. Network request is in a asynchrony way. It is possible that users do not wish to wait for the request finishing. If that happens, we could clean the instance of RequestManager. The delegate property will be reset to nil and the response will be not taken into account as expected. Since we cannot ensure the manager object exists when we get the response, we choose weak here.

Closure and Retain Cycle

The other situation -- closure -- is a bit more complex. All reference to variables in the closure will be held by the closure until out of scope. If we use something like self in the closure, the reference count of self would be added as it referred by other objects. A hidden trap shows here: if we store this closure to a property of self, a retain cycle of "self -> closure -> self" will form. A simple example could describe this case well, we declared a closure to print a property in self:

class Person {
    let name: String
    lazy var printName: ()->() = {
        print("The name is \(self.name)")
    }

    init(personName: String) {
        name = personName
    }

    deinit {
        print("Person deinit \(self.name)")
    }
}

func application(application: UIApplication!,
        didFinishLaunchingWithOptions launchOptions: NSDictionary!)
        -> Bool
{
    // Override point for customization after application launch.
    var person: Person = Person(personName: "James")
    person.printName()

    return true
}

// Output:
// The name is James

Person class has a property called printName, which is a closure containing self. When we init a person object, use it to print name and then go beyond to the scope, the person object should be deinited and released. But in fact, printName closure is always holding person object. It is a leak!

When retain cycle happens in closure, we need to add an annotation to tell the compiler that we do not want to hold self in the closure. Change printName to:

lazy var printName: ()->() = {
    [weak self] in
    if let strongSelf = self {
        print("The name is \(strongSelf.name)")
    }
}

Now, the memory could be released correctly:

// Output:
// The name is XiaoMing
// Person deinit XiaoMing

If we can ensure self will not be released, we can change weak to unowned in the example above. By doing so, we can avoid using strongSelf to check the optional value. unowned also means a promise of the life cycle of self. Nevertheless, if self is released unexpected during the process, unowned has a possibility to cause a crash. We need to think twice to use weak or unowned when we need to make a choice.

This kind of annotation appears in front of parameter list of closure, and placed inside the brackets. If there are multiple elements have to be annotated, use comma to separate them in the same brackets.

// Original
{ (number: Int) -> Bool in
    //...
    return true
}

// Annotated
{ [unowned self, weak someObject] (number: Int) -> Bool in
    //...
    return true
}