Error in Swift class: Property not initialized at super.init call
Quote from The Swift Programming Language, which answers your question:
“Swift’s compiler performs four helpful safety-checks to make sure
that two-phase initialization is completed without error:”Safety check 1 “A designated initializer must ensure that all of the
“properties introduced by its class are initialized before it
delegates up to a superclass initializer.”Excerpt From: Apple Inc. “The Swift Programming Language.” iBooks.
https://itunes.apple.com/us/book/swift-programming-language/id881256329?mt=11
Error in Swift class: Property not initialized at super.init call - How to initialize properties which need use of self in their initializer parameter
You just have to invert the order super.init/properties in your initializer:
required init(coder aDecoder: NSCoder) {
self.datasourceOfflineVideos = ASDataSource(tableViewController: self)
self.datasourceOnlineVideos = ASDataSource(tableViewController: self)
super.init(coder: aDecoder)
}
instance properties comes first, then the superclass initializer can be invoked. But that's not possible in your case, because you are referencing self
.
The workaround in this case is to make the properties implicitly unwrapped optionals:
var datasourceOnlineVideos:ASDataSource!
var datasourceOfflineVideos:ASDataSource!
Since optionals don't need to be initialized, you can safely initialize them after the super.init
method has been called. Being implicitly unwrapped, you use them as any other non optional property.
This pattern is used by Apple in several classes, including UIViewController
: when you add an outlet from IB, the component property is always declared as implicitly unwrapped. That's because the control itself is not instantiated in the initializer, but at a later stage.
Property 'self.*' not initialized at super.init call
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:
- optional property
- property with default value
- lazy property
swift Property not initialized at super.init call
You can fix this by adding a line to set notificationStyle
to a default value in init?(coder aDecoder: NSCoder)
:
required init?(coder aDecoder: NSCoder) {
self.notificationStyle = .numberedSquare //<-- Here
super.init(coder: aDecoder)
setup(notificationStyle: notificationStyle)
}
You have to do this because in your declaration of notificationStyle
, there's no default value and it must have a value before calling super.init
. In your other initializers, you set it based on the incoming arguments.
This is an initializer that it sounds like you're not using anyway, but it is required with UIView
s that we implement this required initializer.
Error: Property 'self.gameArea' not initialised at super.init call
I would recommend you to read about initialization process. Swift preforms two step initialization. First phase is intialization of all stored properties. Also Swift compiler perform few safety checks to make sure two phase initialization is performed correctly. This is from the docs:
Safety check 1
A designated initializer must ensure that all of the properties introduced by its class are initialized before it delegates up to a
superclass initializer.
So you can either initialize your property inside of an initializer:
required init?(coder aDecoder: NSCoder) {
self.gameArea = CGRect()
super.init(coder: aDecoder)
}
or at property declaration (and optionally declaring it as var):
var gameArea = CGRect()
If you don't make it var, after initialization (at declaration) you won't be able to change it later on. Same goes when you initialize a property inside of an initializer. If it is a let constant, further modifications are not possible.
Use of 'self' in property access 'model' before super.init initializes self super.init(brand: brand, model: model)
You are calling the superclass init
method to initialize part of your subclass. However, before you have initialized it, you passed an uninitialized variable. Simply add those variables into the parameter of the Piano
:
init(hasPedals: Bool, brand: String, model: String)
Referencing self in super.init
Short answer:
You cannot capture and use self
as a value before super.init
returns. In your case, you are trying to "pass" self
to super.init
as an argument.
As per why the second part works, simply because without using self
in it, it does not capture self
, thus it does not use self
as a value.
If you don't want to use self
in the closure, then you don't need to worry about strong
/weak
reference there, because there is no reference to self
there at all (since it was not captured). No danger of retain cycle.
Short sidenote about "using self
as a value" - you can use self
on the left-hand side of an assignment to refer to properties of the self
when initializing them:
let myProperty: String
init(with myProperty: String) {
// this usage of self is allowed
self.myProperty = myProperty
super.init(nibName: nil, bundle: nil)
}
Longer answer with references and stuff:
As per documentation:
Safety check 4
An initializer cannot call any instance methods, read the values of any instance properties, or refer to self as a value until after the first phase of initialization is complete.
First phase of initialization is ended by calling super.init
, when the
From the same documentation:
Phase 1
A designated or convenience initializer is called on a class.
Memory for a new instance of that class is allocated. The memory is not yet initialized.
A designated initializer for that class confirms that all stored properties introduced by that class have a value. The memory for these stored properties is now initialized.
The designated initializer hands off to a superclass initializer to perform the same task for its own stored properties.
This continues up the class inheritance chain until the top of the chain is reached.
Once the top of the chain is reached, and the final class in the chain has ensured that all of its stored properties have a value, the instance’s memory is considered to be fully initialized, and phase 1 is complete.
So only after calling super.init
you are allowed to use self
as value:
Phase 2
Working back down from the top of the chain, each designated initializer in the chain has the option to customize the instance further. Initializers are now able to access self and can modify its properties, call its instance methods, and so on.
Finally, any convenience initializers in the chain have the option to customize the instance and to work with
self
.
Now I am not surprised at all that when you try to use self
as a value in a capture list of the closure, that it crashes. I am more surprised that the compiler does allow you to do it - now I guess it's an edge case for which error handling wasn't implemented.
In the second case:
Action(title: "Yes", {
//Blank.. doesn't reference `self` in any way (weak, unowned, etc)
})
You don't really capture self
, that's why it is allowed and it works. But you don't have access to self
there. Try to add there some code that uses self
and the compiler will complain:
So in the end, if you want to use self
in the closure, you will have to find a way how to first call super.init
and only after that add self
capturing closures to the properties.
Related Topics
Disable iOS Simulator 'Connect Hardware Keyboard' Programmatically
"Could Not Inspect Application Package" Xcode
How to Call Https Url in Uiwebview
How to Change Tint Color of Uialertcontroller
Nsdata to Nsstring with JSON Response
Not Getting the Email Using Google Authentication in Firebase
How to Animate Changing a Uilabel's Textalignment
Sequence Animation Using Caanimationgroup
Where Does a Swift iOS Application Begin Its Life
Wkwebview and Uimenucontroller
Get Sms Broadcast with Text Body Without Jailbreak But Private Frameworks in iOS
Array of Multiple Url's Nsfilemanager Swift
Itunes Connect: Can't See Build
How to Remove All References for Outlet
Nsinteralinconsistencyexception - Uikeyboardlayoutalignmentview
The 'Pods' Target Has Transitive Dependencies That Include Static Binaries' When Installing Gcm
Nsstrikethroughstyleattributename , How to Strike Out the String in iOS 10.3
Application Is "Ready to Sale" But Not Reflected on Itunes Store