问题
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) {
_doFoo(fooObject)
}
}
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 Foo
class with T = MyType
by passing self
in the init method of the Foo
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 Foo
object with T == MyType
this should technically work yes?
回答1:
This actually doesn't appear to be anything to do with your generics or protocol conformance. It's simply that you're trying to access self
in your property assignment before self
has been initialised (default property values are assigned during initialisation).
The solution therefore is to use a lazy property like so:
lazy var fooInstant : Foo<MyType> = Foo(_dep : self)
This will now be created when it's first accessed, and therefore after self
has been initialised.
回答2:
It is very much important to understand the context of self
in the place where it is used. In that context, self
doesn't mean an instance of MyView
.
You can, however get it to work by doing this:
let fooInstant : Foo<String> = Foo.init(_dep : MyView())
I cannot say more without understanding what you want to do here.
回答3:
So seems like this works
public class MyView : UIViewController, FooProtocol {
var fooInstant : Foo<MyType>!
public func initializeFooInstant(){
fooInstant = Foo.init(_dep : self)
}
func doFoo(fooObject : MyType) {
...
}
}
I think system does not let you access self to initialise let properties because there is no guarantee that self is fully initialised when your let property is being initialised.
In the above case you will just have to make sure that fooInstance is initialised before accessing it else the program will crash.
Hope this helps.
来源:https://stackoverflow.com/questions/36996573/not-able-to-pass-self-which-implements-a-protocol-to-init-method-of-a-class-in