Bhargav Bhargav - 2 years ago 73
Swift Question

Not able to pass self (which implements a protocol) to init method of a class instantiation.(Swift)

I have a protocol like so

public protocol FooProtocol {
associatedType someType

func doFoo(fooObject:someType) -> Void

I have a class that implements this protocol

public class Foo<T> : FooProtocol {
private let _doFoo : (T) -> Void

init<P : FooProtocol where P.someType == T>(_dep : P) {
_doFoo = _dep.doFoo

public func doFoo(fooObject: T) {

Everything upto here looks good to me, Now in another class I implement the FooProtocol with
someType = MyType
, then when I try to initialize the
class with
T = MyType
by passing
in the init method of the
class I get a compilation error, what am I doing wrong here?

Error message:

" Cannot invoke init with an argument list of type
(_dep: NSObject -> () -> MyView)

public class MyView : UIViewController, FooProtocol {

func doFoo(fooObject : MyType) {

// Here I want to initialize the Foo<T> class
let fooInstant : Foo<MyType> = Foo.init(_dep : self)
// I get the error message on the above line the error
// message reads "Cannot invoke init with an argument list
// of type `(_dep: NSObject -> () -> MyView)`

Isn't self conforming to FooProtocol with
someType == MyType
, and since I am trying to init a
object with
T == MyType
this should technically work yes?

Answer Source

This actually doesn't appear to be anything to do with your generics or protocol conformance. It's simply that you're trying to pass self before self has been initialised (to be clear, this means that self refers to the class itself in that context – not an instance of the class).

The solution is to use a lazy property like so:

lazy var fooInstant : Foo<MyType> = {
    return Foo.init(_dep : self)

This will now be created when it's first accessed, ensuring that self has been initialised.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download