在 Swift 中,类似以下内容应该可以完成您的任务,但它与对应的 ObjC 不同:
typealias GPUImageOutput = UIImage
@objc protocol GPUImageInput {
func lotsOfInput()
}
class GPUImageOutputWithInput: GPUImageOutput, GPUImageInput
{
func lotsOfInput() {
println("lotsOfInput")
}
}
// ...
var someGpuImage = GPUImageOutput()
var specificGpuImage = GPUImageOutputWithInput()
for image in [someGpuImage, specificGpuImage] {
if let specificImage = image as? GPUImageInput {
specificImage.lotsOfInput()
} else {
println("the less specific type")
}
}
更新:现在我明白你在哪里/为什么有这些类型......
GPUImage 似乎有一个 swift 示例,可以做你想做的,尽可能 Swift-ly。
见here:
class FilterOperation<FilterClass: GPUImageOutput where FilterClass: GPUImageInput>: FilterOperationInterface {
...
type constraint syntax 也可以应用于函数,并且使用 where clause,这可能与您直接在 Swift 中获得的一样好。
我越是试图了解如何移植这个有些常见的 objc 比喻,我就越意识到这是最 Swift 的方式。当我看到 GPUImage 本身 中的示例时,我确信这至少是您的答案。 :-)
更新 2:所以,除了我上面链接到的使用 Swift 的特定 GPUImage 示例之外,我越来越多地想到这一点,要么使用 where 子句来保护 setter 函数,要么使用可计算属性来过滤set 功能似乎是唯一的出路。
我想出了这个策略:
import Foundation
@objc protocol SpecialProtocol {
func special()
}
class MyClass {}
class MyClassPlus: MyClass, SpecialProtocol {
func special() {
println("I'm special")
}
}
class MyContainer {
private var i: MyClass?
var test: MyClass? {
get {
return self.i
}
set (newValue) {
if newValue is SpecialProtocol {
self.i = newValue
}
}
}
}
var container = MyContainer()
println("should be nil: \(container.test)")
container.test = MyClass()
println("should still be nil: \(container.test)")
container.test = MyClassPlus()
println("should be set: \(container.test)")
(container.test as? MyClassPlus)?.special()
输出:
should be nil: nil
should still be nil: nil
should be set: Optional(main.MyClassPlus)
I'm special
(或者,您也可以使用precondition(newValue is SpecialProtocol, "newValue did not conform to SpecialProtocol") 代替is 检查,但这就像assert() 在不满足情况时会使应用程序崩溃。取决于您的需要。)
@rintaro 的答案是一个很好的答案,并且是使用 where 子句作为保护的一个很好的例子(无论是功能上的还是 Swift 上的)。但是,当存在可计算属性时,我只是讨厌编写 setFoo() 函数。再说一次,即使使用可计算属性也有代码异味,因为我们似乎无法对set'er 应用泛型类型约束,并且必须在线进行协议一致性测试。