2017-02-20 6 views
2

クラスでは、クロージャパラメータを宣言するときにクラス自体を参照する方法はありますか? Fooを構築するときになるように、以下の例では スイフトで自分のタイプを参照していますか?

Selfの代わりに、どのようなタイプを配置するために、閉鎖パラメータも AnotherFooため Fooと同様になりますか?

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

、私はあなたができるとは思わないので:あなたはパラメータがある知っている型にキャストタイプなどがありますが、初期化関数に渡す閉鎖中

使用FooBase、。うまくいけば、ここの真の達人はより良い答えを得ることができます。クラス階層に関しては、これは横向きですが、正しいのでしょうか?これはどの言語でもできますか? – dfd

+0

関連(dupe?):[Self in init params](http://stackoverflow.com/q/40055862/2976878)。しかし、あなたの設定は安全ではありません。非最終クラスの '((Self) - > Void)型のストアドプロパティを持つことはできません。 'Foo'では'(Foo) - > Void'型の値を保持できます。しかし、あなたが 'FooBase'にアップキャストすれば、' FooBase(FooBase) - > Void'と静的に型付けされています。これは 'AnotherFoo'パラメタで呼び出すことができます - 違法です(' AnotherFoo'≠ 'Foo')。 – Hamish

+0

*完全に正しいとする - 私はupvotedと綴り正しいそれを根絶した。謝罪。 – dfd

答えて

1

スウィフトはあなたが望むことをあなたに許してくれるとは思っていませんが、近づくことはできます。根こそぎ

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 { 
      // ... 
     } 
    }) 
} 
関連する問題