无法将self(实现协议)传递给类实例化的init方法。(Swift)

时间:2016-05-03 05:51:27

标签: ios swift swift2 swift-protocols

我有一个像这样的协议

public protocol FooProtocol {
    associatedType someType

    func doFoo(fooObject:someType) -> Void
}

我有一个实现此协议的类

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)
    }
}

这里的所有内容对我来说都很好,现在在另一个类中我使用someType = MyType实现FooProtocol,然后当我尝试通过传递{{1}来FooT = MyType时在self类的init方法中我收到编译错误,我在这里做错了什么?

错误讯息:

  

“无法使用类型Foo

的参数列表调用init
(_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)` } 不能自我符合FooProtocol,并且由于我尝试使用someType == MyType初始化Foo对象,这在技术上应该可行吗?

3 个答案:

答案 0 :(得分:4)

这实际上似乎与您的泛型或协议一致性无关。您只是在初始化self之前尝试访问属性分配中的self(在初始化期间为分配默认属性值)。

因此,解决方案是使用如下的惰性属性:

lazy var fooInstant : Foo<MyType> = Foo(_dep : self)

现在将在首次访问时创建,因此在初始化self之后。

答案 1 :(得分:3)

了解self在其使用地点的背景非常重要。在此上下文中,self并不代表MyView的实例。

然而,你可以这样做:

let fooInstant : Foo<String> = Foo.init(_dep : MyView())

如果不了解你想在这里做什么,我不能多说。

答案 2 :(得分:0)

看起来似乎有效

public class MyView : UIViewController, FooProtocol {

    var fooInstant : Foo<MyType>!

    public func initializeFooInstant(){
        fooInstant  = Foo.init(_dep : self)
    }


    func doFoo(fooObject : MyType) {
    ...
    }
}

我认为系统不允许您访问self来初始化let属性,因为无法保证在初始化let属性时self已完全初始化。

在上面的例子中,您只需要确保在访问fooInstance之前初始化它,否则程序将崩溃。

希望这有帮助。