【发布时间】:2017-02-08 07:54:25
【问题描述】:
我正在尝试实现一个简单的多代表情况:
protocol Subscribable: class {
associatedtype Subscriber: AnyObject
var subscribers: NSHashTable<Subscriber> { get }
}
protocol ControllerSubscriber: class {
func controllerDidSomething()
}
class Controller: Subscribable {
typealias Subscriber = ControllerSubscriber
var subscribers = NSHashTable<Subscriber>.weakObjects() // Error
}
错误:不支持将“ControllerSubscriber”用作符合协议“AnyObject”的具体类型。
我的问题是:
- 这个错误到底是什么意思?
- 我尝试做的事情失败的基本概念是什么?
- 为什么“不支持”?
当然,我该如何解决这个问题?从实际解决方案的意义上说,不是解决方法。
我很难理解 Swift 的泛型系统。我似乎经常遇到这样看似简单的情况。我只是想把一个符合协议的东西放到另一个东西中:(。我想知道我的想法哪里出错了,这样我就可以修复它,再也不用看到这些错误了。
有this related question,但请注意答案只提供解决方法,没有解释或解决方案。
【问题讨论】:
-
查看问答Protocol doesn't conform to itself?(应该回答您的前 3 个(甚至可能是最后一个)问题)和Unable to use protocol as associatedtype in another protocol in Swift,应该回答您的最后一个问题。
-
整个问题是协议并不总是符合它们自己——因此你不能使用抽象类型(例如
ControllerSubscriber)作为符合AnyObject的具体类型。 -
迟到的回复:感谢您提供的链接,这是一个很好的起点!从我目前所读的所有内容来看,似乎是“这是因为它是,但没有人知道为什么。”老实说,像这样的东西真的降低了我对 Swift 的热情。我没有看到自己为我想使用此订阅者模式的所有情况编写类型擦除的包装器。反正。在第二个链接中,您提出了几种替代解决方案。除了类型擦除的包装器之外,您在这种情况下是否看到任何替代方案?再次感谢您的回复。
-
取决于您的
subscribers属性是否需要是符合ControllerSubscriber的异构元素类型的NSHashTable。如果是这种情况,那么据我所知,类型擦除是您唯一的选择。如果您的subscribers属性只需要是符合ControllerSubscriber的同质元素的NSHashTable,那么您可以通过在Controller中引入通用占位符来解决问题,以便在哈希表。尽管 AFAIK,但这些是目前解决您的问题的唯一两个实用解决方案。 -
非常感谢您的帮助!