Property 'self.*' not initialized at super.init call
Asked Answered
D

3

23

I just updated my xcode to 6.3.1. The problem is I got this weird error message since Swift 1.2. I got this kind of error message

/Users/MNurdin/Documents/iOS/xxxxx/Library/SideBar.swift:32:15: Property 'self.originView' not initialized at super.init call

/Users/MNurdin/Documents/iOS/xxxxx/Library/SideBar.swift:38:20: Immutable value 'self.originView' may only be initialized once

on this code

let originView:UIView?

override init() {
        super.init() //error here

    }

    init(sourceView:UIView, menuItems:Array<String>){
        super.init() //error here
        originView = sourceView //error here
Deceleron answered 27/4, 2015 at 8:14 Comment(1)
This could be your problem: #29632300Goofy
G
29

You have to initialize all property before you call super.init in any init method

So,change this before you call super.init()

originView = sourceView //error here

Exception:

  1. optional property
  2. property with default value
  3. lazy property
Grubb answered 27/4, 2015 at 8:23 Comment(2)
I already initialize my property. check my question. Still error.Deceleron
This answer doesn't quite seem to match the code in the question. The problem in this case isn't where the value is being assigned, the problem is that you can't declare an optional property with let.Raviv
B
16

Make your originView nullable by

var originView: UIView?. 

If your originView is not nullable you have to provide a default value before calling

super.init().
Berdichev answered 27/4, 2015 at 8:35 Comment(2)
let originView:UIView!. you declared originView as constant using "let". it should "var". when you are using "let" you wont be allowed to change it's value again other than during declaration.Berdichev
you are correct, sorry my mistake. let me try first.Deceleron
C
6

From Apple's “The Swift Programming Language” book:

“Swift’s compiler performs four helpful safety-checks to make sure that two-phase initialization is completed without error”

“A designated initializer must ensure that all of the “properties introduced by its class are initialized before it delegates up to a superclass initializer.”

Basically you have to ensure that your instance variables are in a consistent state before you do anything, including calling methods.

class YourClass {
    var view: UIView
    init(view: UIView) {
        self.view = view
    }
}

well in your case you can make it a new UIView:

let originView = UIView()

or make it nullable

let originView: UIView?

or make a lazy property instead:

lazy var originView: UIView = {
    let view = UIView(frame: CGRect(x: 0, y: 0, width: 375, height: 200))
    // customize it
    return view
}()

when using lazy instantiation you can pass a method:

lazy var originView: UIView = self.createView()

func createView() -> UIView {
    let view = UIView(frame: CGRect(x: 0, y: 0, width: 375, height: 200))
        // customize it
        return view
}
Cunaxa answered 18/3, 2017 at 16:23 Comment(2)
What is a better practice? Use nullable or lazy property?Kopp
@Kopp it depends really. There's no best way, you need to think how your class should behave, what states should it have and depending on the info you write code. Try to describe your classes on paper first and then code, soon you'll do everything in your mind automatically.Cunaxa

© 2022 - 2024 — McMap. All rights reserved.