Nope, I don't think it is possible because you can use Self
only in protocols as it is just a placeholder for the type that is going to conform to that protocol. It is not a real type like A
or B
so you can't use that upon defining classes as if it is Any
or AnyObject
.
So let's create a protocol which forces conforming types to implement init(finishBlock:)
initializer:
protocol BlockInitializable {
init(finishBlock: ((_ operation: Self) -> Void)?)
}
class A: BlockInitializable {
init() {}
convenience required init(finishBlock: ((_ operation: A) -> Void)?) {
self.init()
finishBlock?(self)
}
}
and you'll get the following error:
Protocol "Blocked" requirement init(finishBlock:) can not be satisifed by a non-final class (A)
because it uses "Self" in a non-parameter, non-result type position.
and what's worse you'll lose the generic type Self
of parameter operation.
To fix this, you should mark your class as final or use struct which is a final type. However, you'll lose the ability of subclassing those types. The reason why you have to do that and why you can't use Self
in subclassed types is explained here so I recommend you go take a look at it.
I'll go with the latter option and use struct:
protocol Initializable {
init()
}
protocol BlockInitializable: Initializable {
init(finishBlock: ((_ operation: Self) -> Void)?)
}
extension BlockInitializable {
init(finishBlock: ((_ operation: Self) -> Void)?) {
self.init()
finishBlock?(self)
}
}
then define A
and B
as struct:
struct A: BlockInitializable {
}
struct B: BlockInitializable {
func fooOnlyInB() {
print("Only in B")
}
}
and you'll be able to do the following:
let blockA = A { operation in
print("Only in A")
}
let blockB = B { operation in
operation.fooOnlyInB()
}
You can download the playground from here.