Software development

Broken UITableViewController initializer in Swift

Topics
iOS, Swift, Cocoa

Update: This should be fixed in the latest iOS 9.0 beta, so there is some hope left.

There has been information about this elsewhere as well, but my encounter with the UITableViewController initialization bug was quite different from the mentioned, so it might be worth sharing. Since deep down it is the same problem and searching for answers surprisingly didn't produce that many results, I thought of writing this blog post just to give more visibility to the problem.

Let us consider the following example that can be pasted directly to the Playground:

import UIKit

struct StructWithSideEffects {
    init() {
        println("Called struct initializer")
    }
}

class TableViewController: UITableViewController {
    let ourStruct = StructWithSideEffects()
}

let vc = TableViewController(style: .Plain)

Here we have a single instance of TableViewController and inside of it we have a single instance of StructWithSideEffects, so it would make sense that the println(...) is called just once, right? However, because the broken UITableViewController calls UIViewController.init, which in turn calls UITableViewController.init(nibName: String!, bundle: String!), which does the whole initialization again, it is actually called twice.

So this simple bug not only makes subclassing UITableViewController difficult, but it also causes bugs in cases where UITableViewController is not being subclassed at all. I don't think there are any clean workarounds, personally I just tried to avoid side effects when initializing structs or classes, and in cases where that couldn't be avoided used a variable which is set elsewhere. I'm really hoping Apple fixes this in the next releases, even if it breaks someone's workaround...