Reputation: 8395
When in a class, how to refer to the class itself when declaring closure parameters?
In the example below, what type to place in place of Self
so that when constructing Foo
, the closure parameter also becomes Foo
and similarly for 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
// ...
})
}
Upvotes: 2
Views: 158
Reputation: 3169
I don't think Swift allows you to do what you want, but you can get close.
Use FooBase as the type, but in the closures you pass to the init functions, cast to the type that you know the parameter is:
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 {
// ...
}
})
}
Upvotes: 1