【发布时间】:2020-02-23 08:02:26
【问题描述】:
我目前正在用 Swift 编写一个可重用的 UI 组件,它应该可以从 Obj-C/Swift 世界中使用(这是一个混合项目)。我定义了一个没有任何关联类型的@objc 协议(因为@objc 协议不允许使用这些类型)。在组件中的一个方法中,我需要将协议存储为一种类型,并且需要找到特定条目的索引,有点类似于以下 -
func select<T: Itemable>(_ item: T) {
guard let itemIndex = items.index(of: item) else {
return
}
//more stuf
}
其中items 是Itemable(协议)类型的数组。
但是,我收到错误消息,说我不能将其用作符合 Equatable 的类型,因为 equatable 具有静态要求。
Itemable 定义如下-
@objc protocol Itemable {
//methods and properties
}
另外,不确定如何使其符合 equatable。显然,以下内容有所帮助,但不确定原因-
func ==<T: <Itemable>>(lhs: T, rhs: T) -> Bool {
return lhs.aProperty == rhs.aProperty
}
在我看来它可能需要擦除类型,但不知道如何去做。
这是协议的精简版,显示了所有不同类型的方法和属性 - 它实际上没有任何静态或关联类型。
@objc protocol Itemable {
typealias voidBlock = () -> Void
var color: UIColor { get }
var screenParameters: [String : String] { get }
var screenView: String { get }
var iconImage: UIImage? { get }
@objc var accessibilityLabel: String? { get }
}
extension Array where Element: Itemable {
func index(of element: Element) -> Int? {
index(where: { $0.screenView == element.screenView })
}
}
【问题讨论】:
-
您能否显示更多有关
guard语句的代码。你能显示它所在的方法/类吗? -
完成!请再看一遍。
-
我猜
items是[Itemable]?在这种情况下,我认为一种方法(不确定是否是唯一方法)是做as NSArray并在NSArray中使用index(of:)。
标签: objective-c swift generics protocols type-erasure