I'm trying to create a static method on a generic class which takes in a closure as parameter and creates an instance of the class and passes it the closure. The catch is that I want to subclass this and ensure that the closure conforms to any subclass I use.
I know that you can use "Self" as a return type for a static method, but when I try to use it in the method header, I get the following error:
"'Self' is only available in a protocol or as the result of a method in a class"
I'd like to do something like this:
class GenericClass: NSObject {
required override init() {
super.init()
}
static func createAndExecuteAsync(block: (Self) -> Void) {
DispatchQueue.global().async {
let instance = self.init()
block(instance)
}
}
}
class OtherClass: GenericClass {
// ...
}
Somewhere else...
OtherClass.createAndExecuteAsync { (instance: OtherClass) in
// Do stuff to instance
}
UPDATE:
Thanks to Hamish's solution in this post, I'm closer to a solution. I can use Self in the desired way if I first create a protocol for my generic class. However that forces me to make OtherClass final, which isn't desirable for my situation.
Without making OtherClass final, I get the following error:
Protocol 'GenericClass' requirement 'createAndExecuteAsync(block:)' cannot be satisfied by a non-final class ('OtherClass') because it uses 'Self' in a non-parameter, non-result type position.
Here's what it would look like:
protocol GenericClass {
init()
static func createAndExecuteAsync(block: @escaping (Self) -> Void)
}
extension GenericClass {
static func createAndExecuteAsync(block: @escaping (Self) -> Void) {
DispatchQueue.global().async {
let instance = self.init()
block(instance)
}
}
}
final class OtherClass : GenericClass {
var myProperty = 1
required init() { }
}
// Somewhere else...
OtherClass.createAndExecuteAsync { (instance) in
instance.myProperty = 2
}