ios – 使用Swift中的Comparable扩展@objc协议

我正在尝试使用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’ cannot refine non-@objc protocol
‘Equatable’

>

Protocol ‘Option’ can only be used as a generic constraint
because it has Self or associated type requirements

你有什么建议如何解决这个问题?

解决方法

只能在Swift世界中生活,因此您无法将其扩展到Objective-C将使用的协议.尝试这样做会导致错误#1

具有Self要求的协议(即,协议声明中的至少一个方法包含Self)不能用作函数或变量声明的参数,仅作为泛型子句的参数,例如,func doSomething< T:Option>(参数:T).

从Option协议声明中删除Equatable,并在Option上声明== as generic将解决编译错误.至于排序,你也可以重载<运算符,并通过该运算符排序(无需实现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],并且由于<的不明确性,排序调用将无法编译.操作符.您需要将c显式声明为[Option]以利用重载运算符.

相关文章

当我们远离最新的 iOS 16 更新版本时,我们听到了困扰 Apple...
欧版/美版 特别说一下,美版选错了 可能会永久丧失4G,不过只...
一般在接外包的时候, 通常第三方需要安装你的app进行测...
前言为了让更多的人永远记住12月13日,各大厂都在这一天将应...