在Swift中扩展@objc协议以使其符合Hashable

5

我有一个带有以下实现的@objc协议:

@objc public protocol Document: class {
   var data: Data? { get }
   var image: UIImage? { get }

   func generatePreview()
} 

我想在一个[Document: Int]字典中使用它,但是自然会出现以下错误:

类型'Document'不符合协议'Hashable'

问题是我不知道如何使其符合Hashable,因为它是一个@objc协议,而Hashable只适用于Swift。如果我尝试让它符合Hashable,则会出现以下错误:

@objc协议'Document'无法优化非@objc协议'Hashable'

这个协议被用作@objc方法中的属性,我希望保持此方法作为@objc方法,因为它是@objc委托协议的一部分。这个协议长这样:
@objc public protocol MyClassDelegate: class {

    @objc func methodOne(parameter: [Document: Int])

}

有什么想法吗?

2
声明协议为 @objc 的目的是什么? - Ahmad F
正如我回答@aaoli的那样,它被用作@objc方法中的参数。 - kikettas
好的,ObjC并不真正关心字典键类型,因此对于@objc方法,您可以使用NSDictionary - user28434'mstep
我知道我可以使用NSDictionary,但我之所以问这个问题,是因为我想找到一种允许我使用类型安全字典的解决方案。 - kikettas
1
请参考 https://dev59.com/-6rka4cB1Zd3GeqPYRfB#49479962 了解此问题的另一种版本。简短的答案是:不要将协议用作字典中的键。这永远不会顺利进行,所有的解决方法都很麻烦。问题不在于 @objc,而在于协议和 Hashable。 - Rob Napier
确切地说,问题不在于 @objc,而是协议和 Hashable。我猜现在还没有一个“好”的解决方案,或者至少 Swift 还没有为此做好准备。我会再考虑一下,并重新评估 Document 类是否应该成为协议。感谢 @RobNapier! - kikettas
1个回答

3
您可以使用[AnyHashable: Int],它是一种类型擦除的可哈希值。
我假设您已经拥有名为Document的协议:
@objc public protocol Document: class {
    var data: Data? { get }
    var image: UIImage? { get }

    func generatePreview()
}

你的协议方法methodOne将接受[AnyHashable: Int]:

@objc public protocol MyClassDelegate: class {

     @objc func methodOne(parameter: [AnyHashable: Int])

}

这是一个有点复杂的问题,经过一些研究,我同意 @Rob Napier 的看法。

不要将协议作为字典中的键。这很容易出问题,而且所有的解决方法都很麻烦。

我的回答可能不完美,但希望能帮助您消除错误。


1
问题在于我不能仅仅从方法声明中删除@objc,因为该协议被用作@objc方法的参数。 - kikettas
@kikettas 你的意思是你正在使用可选函数还是只是使用 @objc 的函数?正如我所指出的,为了使用 Hashable,你需要摆脱它!可以更新你的问题并提供完整的细节吗? - AaoIi
我更新了问题,并提供了更多信息,我认为这些信息可以回答你的问题。 - kikettas
1
好的,你编辑了答案。我之前没有看到它。我猜这应该是目前唯一解决方法,如果我必须保留@objc。我也同意你的观点,应该避免使用协议作为字典中的键。感谢你的帮助! - kikettas
让我们在聊天中继续这个讨论 - kikettas
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接