我正在尝试使用Option
扩展我的协议Comparable
以使用简单的.sort()
方法。
仅在简短示例下使用Equatable
来显示错误。
@objc protocol Option: Equatable {
var title: String { get }
var enabled: Bool { get }
var position: Int { get }
}
func ==(lhs: Option, rhs: Option) -> Bool {
return lhs.position == rhs.position
}
Option
协议必须标记为@objc
或从NSObjectProtocol
继承,因为它将与UIKit
一起使用。
错误:
@objc protocol' Option'无法改进非@objc协议 ' Equatable'
协议'选项'只能用作通用约束 因为它有自我或相关的类型要求
你有什么建议如何解决这个问题?
答案 0 :(得分:4)
Equatable
仅存在于Swift世界中,因此您无法将其扩展为Objective-C将使用的协议。尝试这样做会导致错误#1
具有Self
要求的协议(即协议声明中至少有一个方法包含Self
)不能用作函数或变量声明的参数,仅作为泛型子句的参数,例如func doSomething<T: Option>(argument: T)
。
从Equatable
协议声明中删除Option
,并在==
上将Option
声明为通用将解决编译错误。至于排序,您还可以重载<
运算符,并通过该运算符排序(无需实现Comparable
):
@objc protocol Option {
var title: String { get }
var enabled: Bool { get }
var position: Int { get }
}
func ==<T: Option>(lhs: T, rhs: T) -> Bool {
return lhs.position == rhs.position
}
func <<T: Option>(lhs: T, rhs: T) -> Bool {
return lhs.position < rhs.position
}
这允许您将符合协议的对象传递给UIKit
,并在快速代码中对它们进行比较。
class A: NSObject, Option { .. }
class B: NSObject, Option { ... }
let a = A()
let b = B()
a == b // compiles, and returns true if a and b have the same position
let c: [Option] = [a, b]
c.sort(<) // returns a sorted array by the `position` field
关于上述排序代码的一个重要注意事项:如果您未指定c
的类型,则编译器会将其类型推断为[NSObject]
和sort
调用由于<
运算符的模糊性,将无法编译。您需要明确声明c
为[Option]
以利用重载运算符。
答案 1 :(得分:2)
可以通过swift 2.0中引入的新的面向协议的编程功能来解决这个问题
@objc协议'选项'无法优化非@objc协议'Equatable'
正如错误所述,Equatable
协议是一个swift协议,你不能对Obj C上下文
协议'选项'只能用作通用约束,因为它 有自我或相关的类型要求
您可以通过以下方式实现此目的:
@objc protocol Option {
var title: String { get }
var enabled: Bool { get }
var position: Int { get }
}
extension Equatable where Self : Option
{
}
extension Comparable where Self : Option
{
}
func ==(lhs: Option, rhs: Option) -> Bool
{
return lhs.position == rhs.position
}
func <(lhs: Option, rhs: Option) -> Bool
{
return lhs.position < rhs.position
}
func >(lhs: Option, rhs: Option) -> Bool
{
return lhs.position > rhs.position
}
您的课程和实施如下:
class MyClass: Option
{
@objc var title: String = ""
@objc var enabled: Bool = true
@objc var position: Int = 0
init()
{
}
convenience init(title : String, enabled : Bool, position: Int)
{
self.init()
self.title = title
self.enabled = enabled
self.position = position
}
}
let firstObj = MyClass()
let secondObj = MyClass()
let optionArray : [Option] = [firstObj, secondObj]
// Sort array of options
optionArray.sort(<)