Protocol Extension Initializer forcing to call self.init

prat14k

I was just reading the Apple Swift 4 document regarding the Protocol Initializer Requirements and providing a default implementation in the protocol extension.

import UIKit
protocol Protocol {
    init()
}
extension Protocol {
    init() {
        print("SDf")
        self.init() // Line 1
                    // Compiler error occured if this is omitted 
                    //"'self.init' isn't called on all paths before returning from initializer"
    }
}

struct Structure: Protocol {
    init(string: String) {

    }
}

Structure()      // Line 2

Now as you can see, the execution will go into a loop, as by default the structure doesn't have an implementation for init(), so the protocol provided init will be called and it will call itself again, and so it goes into an infinite loop.

Now, knowing this, if I remove Line 1, the compiler gives the error.

Q. Why is it forcing me to use self.init() on Line 1, and how can I get out of this situation?

Hamish

Consider this example:

protocol P {
  init()
}

extension P {
  init() {

  } // error: 'self.init' isn't called on all paths before returning from initializer
}

struct S : P {
  var str: String
}

let s = S()
print(s.str)

Suppose it compiled – we'd be able to create an S value without providing a value for the str property. That's why the compiler is complaining that your protocol extension implementation of init() isn't calling self.init. It needs you to chain to some other initialiser requirement – one that you don't provide a default implementation for (otherwise you could get into a recursive loop, as you found out), and therefore one that the adopting type needs to implement such that it can fully initialise itself.

For example, this is legal:

protocol P {
  init()
  init(str: String)
}

extension P {
  init() {
    self.init(str: "some default")
  }
}

struct S : P {
  var str: String
}

let s = S()
print(s.str) // some default

because now we're chaining to the init(str:) requirement, which S must implement (in this case it's satisfied by the implicit memberwise initialiser).

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

Swift protocol extension self reference issues with init

Protocol Extension Initializer

"self as?" within protocol extension

"Convenience initializer missing a 'self' call to another initializer"

what is 'where self' in protocol extension

Error in Swift class: Property not initialized at super.init call - How to initialize properties which need use of self in their initializer parameter

Swift protocol extension with specific Self type

Why does Swift disallow assignment to self in class init, but not in protocol init?

'self' used before 'self.init' call or assignment to 'self'

Swift: Self.init called multiple times in initializer

Why won't my self.init autofill in a convenience initializer?

Swift protocol forcing the Equatable protocol

Issue with the call hierarchy of a swift protocol extension

Swift: Call self method inside init

'self' used before super.init call

How to call static methods on a protocol if they are defined in a protocol extension?

Swift: Convenience initializers - Self used before self.init call

Swift 5: 'self' used before 'self.init' call

Error of 'self' used before 'self.init' call or assignment to 'self' on init in a different module

iOS Swift convenience initializer self used before self.init called

Subclass of NSViewController: use of 'self' in delegating initializer before self.init is called Error

Protocol-Oriented Programming Extension variable init twice

Swift protocol extension where Self: Equatable doesn't work

Incorrectly Inferred Type in Generic Closure with Protocol Extension Constrained by Self

Objective C syntax corresponding to Swift "extension where self: <some protocol>"

Protocol extension default method causing a "self is immutable" error

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

How can I use self for init in extension in Swift?

Self in protocol