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