non-nominal type X does not support explicit initialization
Solution 1
You just need to use init
explicitly whenever you're initializing a generic parameter rather than a "real" type:
self.c = C.init(modelView: m)
Solution 2
Use C.init(modelView: m)
rather than C(modelView: m)
. That should fix it.
Solution 3
Please check :
In your code you are doing like this C : MainViewControllerInterface, C : UIViewController
.
It is treating C
as ViewController, then there is no init
in ViewController like init(modelView: M)
thats why its throwing error
public class Other<C, M> : NSObject where C : MainViewControllerInterface, M : MainControllerToModelInterface, C.MODELVIEW == M {
var c : C?
override init() {
let m = M()
self.c = C(modelView: m)
super.init()
}
}
Luca Bartoletti
Updated on June 04, 2022Comments
-
Luca Bartoletti almost 2 years
I'm trying to understand what I'm doing wrong with generics in swift.
I created this sample playground
import UIKit public protocol MainControllerToModelInterface : class { func addGoal() init() } public protocol MainViewControllerInterface : class { associatedtype MODELVIEW var modelView: MODELVIEW? {get set} init(modelView: MODELVIEW) } public class MainViewController<M> : UIViewController, MainViewControllerInterface where M : MainControllerToModelInterface { public weak var modelView: M? required public init(modelView: M) { self.modelView = modelView super.init(nibName: String(describing: MainViewController.self), bundle: Bundle.main) } required public init?(coder aDecoder: NSCoder) { fatalError("init(coder:) has not been implemented") } } public class Other<C, M> : NSObject where C : MainViewControllerInterface, C : UIViewController, M : MainControllerToModelInterface, C.MODELVIEW == M { var c : C? override init() { let m = M() self.c = C(modelView: m) super.init() } }
the line
self.c = C(modelView: m)
gives me this errornon-nominal type 'C' does not support explicit initialization
From this other stack overflow question I see that this error in older Xcode versions means
cannot invoke initializer for type '%type' with an argument list of type '...' expected an argument list of type '...'
But in the playground above what is the compiler missing?
I'm on swift4/xcode9.
Update
After following the suggestion
Use C.init(modelView: m) rather than C(modelView: m)
the error changes in:No 'C.Type.init' candidates produce the expected contextual result type '_?'
Than @vini-app suggested to remove the UIViewController to make it works. By I still don't understand why the compiler is not happy when UIViewController is there. Is it not enough to know that C has that valid init method?