Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Init a class with arguments on swift [duplicate]

I am trying to init a class with arguments in Swift. I want to be able to pass an array to the class. Something like let test = MyTestClass(data).

Code:

init(data: [CGFloat]){
    super.init(nibName: "Test", bundle: nil)
    self.data = data
}

required init?(coder decoder: NSCoder) {

    super.init(nibName: "Test", bundle: nil)
}

Error:

enter image description here

like image 375
J.Doe Avatar asked Nov 15 '25 19:11

J.Doe


2 Answers

You can solve the errors by initializing data before calling super also in init(coder and call the appropriate super method in init(coder

let data : [CGFloat]

init(data: [CGFloat]){
    self.data = data
    super.init(nibName: "Test", bundle: nil)
}

required init?(coder decoder: NSCoder) {
    self.data = [CGFloat]()
    super.init(coder: decoder)
}

Alternatively declare data as

var data = [CGFloat]()

then you can write

init(data: [CGFloat]){
    self.data = data
    super.init(nibName: "Test", bundle: nil)
}

required init?(coder decoder: NSCoder) {
    super.init(coder: decoder)
}

In any case you have to call super.init(coder: decoder) in init(coder.

like image 74
vadian Avatar answered Nov 18 '25 11:11

vadian


Swift requires all parameters to be set by the time the initialiser completes. It also requires these parameters to be set before calling another function, which is why the super initialiser is called afterwards, rather than in the first line as required by Objective-C.

In the normal initialiser, you are setting the value of data to the passed in array. But you aren't doing so for the init(coder:) method.

There are two ways to handle this:

One way is to just throw an assertion if the init(coder:) initialiser is called.

required init?(coder decoder: NSCoder) {
    fatalError("Not meant to be initialised this way")
}

The other is to assign a "empty" value:

required init?(coder decoder: NSCoder) {
    data = [CGFloat]() // just set an empty array
    super.init(nibName: "Test", bundle: nil)
}

The method you choose depends on how you want to use the code in your domain. I mostly choose the first option, because calling an initialiser that isn't meant to be used is a developer error, and it is a good idea to just crash for those types of error.

like image 24
Abizern Avatar answered Nov 18 '25 10:11

Abizern