Use of Self in Method Call Before Super.Init Initializes Self', Can't Init Properties Through a Method Call

Use of self in method call before super.init initialises self

You are not calling super.init(frame:) from your init(frame:viewController method. It needs to be done between setting self.currentViewController and calling setup.

init(frame: CGRect, viewController: UIViewController) {
self.currentViewController = viewController

super.init(frame: frame)

setup()
}

You should read the Initialization chapter (especially the Class Inheritance and Initialization section) of the Swift book. Initialization of a class needs to be done in a clearly documented fashion.

Use of self in method call before super.init initializes self', can't init properties through a method call

Form documentation:

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.

You need to set value for instance variable before you call super.init() And after this action you will access to call instance methods. In your case you can do this:

override init (frame : CGRect) {
self.collectionView = UICollectionView()
super.init(frame : frame)
// Now you can call method
self.someMethod()
}

ADD for question's EDIT:

You can't call method before super.init() call because of safety reasons. If you will do it then your method can use some properties which have not yet been initialized in the parent class

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)

self' used in method call 'foo' before 'super.init' call

You should not set instance methods into instance properties even where referencing self.methodName is allowed, which makes reference cycles.

A simple workaround is something like this:

class BrowDownEvaluator: BothEvaluator {
static func onBoth(delegate: FaceTriggerDelegate, newBoth: Bool) {
delegate.onBrowDownDidChange?(browDown: newBoth)
if newBoth {
delegate.onBrowDown?()
}
}

static func onLeft(delegate: FaceTriggerDelegate, newLeft: Bool) {
}

static func onRight(delegate: FaceTriggerDelegate, newRight: Bool) {
}

init(threshold: Float) {
super.init(threshold: threshold, leftKey: .browDownLeft, rightKey: .browDownRight,
onBoth: BrowDownEvaluator.onBoth,
onLeft: BrowDownEvaluator.onLeft,
onRight: BrowDownEvaluator.onRight)
}
}

If you want to access self as an instance of BrowDownEvaluator, things get a little more complicated.

Swift: use of 'self' in method call before super.init initializes self compile error

Just place it under super.init().

The object needs to be initialized first by the super class and then you can do your custom initialization.

override init() {
super.init()
setupAudioSession()
}

Initialising member to class function causes 'self' used in method call error

It might be better to not use a Bool, but rather a nested Enum, which is also more extendible if you wanna add some other modes of haptic feedback later on.

I have a generalized solution for a generalized problem of your question. So either you do:


public class FunctionOwner {

private let mode: Mode

public init(`do` mode: Mode = .default) {
self.mode = mode
}
}


public extension FunctionOwner {

enum Mode {
case foo, bar
}

func fooOrBar() {
switch mode {
case .foo: foo()
case .bar: bar()
}
}
}

private extension FunctionOwner {
func foo() {
print("doing foo")
}

func bar() {
print("doing bar")
}
}

public extension FunctionOwner.Mode {
static var `default`: FunctionOwner.Mode {
return .foo
}
}

// USAGE
FunctionOwner(do: .bar).fooOrBar() // prints "doing foo"
FunctionOwner(do: .foo).fooOrBar() // prints "doing bar"

Or if you for some reason do want to keep the stored Mode, you can do this (might be relevant for your actual question on how you do a workaround of referencing self in the init.):

public class FunctionOwner {

private let _function: (FunctionOwner) -> Void

public init(`do` mode: Mode = .default) {
_function = { functionOwner in
switch mode {
case .foo: functionOwner.foo()
case .bar: functionOwner.bar()
}
}
}
}

public extension FunctionOwner {

enum Mode {
case foo, bar
}

func fooOrBar() {
_function(self)
}
}

// The rest of the code is the same as the example above

Swift. Use of 'self' in method call before all stored properties are initialized

You can't call methods on self before all non-optional instance variables are initialized.
There are several ways to go around that.

  1. Change properties to optionals or implicitly unwrapped optionals
    (not recommended)
  2. Make the buildCircle() method static or just a
    function in the file and call the addSubview() for all the circles
    after all of the properties were initialized and you called
    super.init()
  3. etc. You just have to avoid calls to self before the
    class was initialized.

Use of 'self' in method call 'f' before all stored properties are initialized

It doesn't mean that if you haven't written self with function call f then it will not reference to self as of f is still instance method, so with init it must be called after all the instance properties are initialized means after the the instance of class is initialized. So simply call f() after you initialized the instance property a.

class A {
var a: String
init(a: String) {
self.a = a
f()
}

func f() {
print("HeHe")
}
}


Related Topics



Leave a reply



Submit