2017-02-20 43 views
2

在类中时,如何在声明闭包参数时引用类本身?引用Swift中的自己的类型?

在下面的例子中,到位的Self使构建Foo当放置什么类型的,封闭的参数也变得Foo同样地,对于AnotherFoo

class FooBase { 
    init(completionHandler: (_ myself : Self)) { 
     // ... 
     self.completionHandler = completionHandler 
    } 

    var completionHandler : ((_ :Self) -> Void)? 

    func strategyMethod() { ... } 
} 

class Foo : FooBase { 
    // ... 
    override func strategyMethod() { 
     // do stuff 
     completionHandler?(self) 
    } 
} 

class AnotherFoo : FooBase { 
    // ... 
    override func strategyMethod() { 
     // do other stuff 
     completionHandler?(self) 
    } 
} 

func useFoos { 
    let foo = Foo(completionHandler: {(me : Foo) in 
     // ... 
    }) 
    let anotherFoo = AnotherFoo(completionHandler: {(me : AnotherFoo) in 
     // ... 
    }) 
} 
+0

连根拔起,因为我不认为你可以。希望这里的真正的大师可以有更好的答案。在阶级层次上,这是横向的,正确的?这可以用任何语言来完成吗? – dfd

+0

相关(dupe?):[init in params自身](http://stackoverflow.com/q/40055862/2976878)。但是你的配置无论如何都是不安全的 - 你不可能在非final类中有一个类型为'((Self) - > Void)?'的存储属性。在'Foo'中,它可以保存'(Foo) - > Void'类型的值。但是如果你上传到'FooBase',它现在被静态类型为'(FooBase) - > Void',这意味着你可以用AnotherFoo参数来调用它 - 这将是非法的('AnotherFoo'≠'Foo')。 – Hamish

+0

要完美*正确 - 我upvoted和拼写正确使连根拔起。道歉。 – dfd

回答

1

我不认为Swift允许你做你想做的事,但你可以关闭。

使用FooBase的类型,但你传递给初始化函数,投射到你知道的参数类型的倒闭是:

class FooBase { 
    init(completionHandler: @escaping (_ myself : FooBase) -> Void) { 
     // ... 
     self.completionHandler = completionHandler 
    } 

    var completionHandler : ((_ myself:FooBase) -> Void)? 

    func strategyMethod() { 
    } 
} 

class Foo : FooBase { 
    // ... 
    override func strategyMethod() { 
     // do stuff 
     completionHandler?(self) 
    } 
} 

class AnotherFoo : FooBase { 
    // ... 
    override func strategyMethod() { 
     // do other stuff 
     completionHandler?(self) 
    } 
} 

func useFoos() { 
    let foo = Foo(completionHandler: {(myself_in : FooBase) in 
     // This cast should always succeed when the closure is used as intended 
     if let myself = myself_in as? Foo { 
      // ... 
     } 
    }) 
    let anotherFoo = AnotherFoo(completionHandler: {(myself_in : FooBase) in 
     // This cast should always succeed when the closure is used as intended 
     if let myself = myself_in as? AnotherFoo { 
      // ... 
     } 
    }) 
}