init?(coder: NSCoder) or init?(coder: (NSCoder?))

In this code, I use in some places

    required init?(coder: (NSCoder?)) { 
        // Init some properties
        super.init(coder: coder!)   
    }

And in other places

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        // Init some properties
    }

Both seem to work. Is there a preferred one ? In which cases ? Or should I always use the second one ?

And can super be called at anytime ?

Answered by DTS Engineer in 877320022

Swift’s superclass initialisation rules are complex, so it’s hard to answer questions like this without seeing a concrete example. Anyway, I most commonly see folks hit this when they’re creating a Cocoa view, so let’s look at that:

import AppKit

class MyView: NSView {
    var counter: Int
    
    override init(frame: NSRect) {
        self.counter = 0
        super.init(frame: frame)
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
           // ^ Property 'self.counter' not initialized at super.init call
        self.counter = 0    // A
    }
}

This fails because you have to initialise counter before calling super. Moving line A up a line fixes the problem.

If you have an example of the other behaviour, please share it.

Oh, and this was Xcode 26.2 with the macOS 26.2 SDK.

Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Accepted Answer

Swift’s superclass initialisation rules are complex, so it’s hard to answer questions like this without seeing a concrete example. Anyway, I most commonly see folks hit this when they’re creating a Cocoa view, so let’s look at that:

import AppKit

class MyView: NSView {
    var counter: Int
    
    override init(frame: NSRect) {
        self.counter = 0
        super.init(frame: frame)
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
           // ^ Property 'self.counter' not initialized at super.init call
        self.counter = 0    // A
    }
}

This fails because you have to initialise counter before calling super. Moving line A up a line fixes the problem.

If you have an example of the other behaviour, please share it.

Oh, and this was Xcode 26.2 with the macOS 26.2 SDK.

Share and Enjoy
—
Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thanks Quinn.

My take away is:

  • I have to take care of when super.init is called
  • init?(coder: (NSCoder?)) does not make sense. In fact, I don't even remember where I got this syntax, may be after some deprecation warning (but that was back in 2018).

I shall read carefully the chapter on Initialisation in Swift language book.

init?(coder: NSCoder) or init?(coder: (NSCoder?))
 
 
Q