我有一个协议,它构成了许多类的基础 - 在下面的示例中,StaticFile
和RemoteFile
。我引用了一个指向协议的变量
protocol ContainerDelegate {}
protocol FileProtocol {
var delegate: ContainerDelegate? { get set }
}
class StaticFile: NSObject, FileProtocol {
var delegate: ContainerDelegate?
}
class RemoteFile: NSObject, FileProtocol {
var delegate: ContainerDelegate?
}
class Container: NSObject, ContainerDelegate {
var item: FileProtocol
override init() {}
func something() {
if item.delegate !== self { // This fails
}
}
}
我甚至不关心类型,我只想查看委托是否不是当前对象(通过引用)。使失败线路正常工作的最佳方法是什么?
答案 0 :(得分:4)
您应该尝试向上翻转delegate
,然后检查是否相等:
func something() {
if item.delegate as? Container !== self {
print("hi")
}
}
完整的工作代码示例
protocol ContainerDelegate {}
protocol FileProtocol {
var delegate: ContainerDelegate? { get set }
}
class StaticFile: NSObject, FileProtocol {
var delegate: ContainerDelegate?
}
class Container: NSObject, ContainerDelegate {
var item: FileProtocol
func something() {
if item.delegate as? Container !== self {
print("hi")
}
}
override init() {
item = StaticFile()
}
}
let c = Container()
let c2 = Container()
c.item.delegate = c2
c.something() // hi gets printed
c.item.delegate = c
c.something() // hi does **not** get printed
答案 1 :(得分:2)
这里的问题是ContainerDelegate
不要求符合类型是引用类型。您可以编写一个符合此协议的struct
,并使用===
和!==
作为结构并不合理。 (===
和!==
运算符采用AnyObject?
个参数,只有类对象可以作为AnyObject传递。)
解决此问题的一种方法是使用protocol ContainerDelegate: class {}
,这需要引用语义,并允许您编写item.delegate !== self
。
另一种方式,正如luk2302指出的那样,因为你只关心对象是否与self
相同,所以你可以先尝试将它转换为与self
相同的类型,然后再进行比较