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]以利用重载运算符.

相关文章

UITabBarController 是 iOS 中用于管理和显示选项卡界面的一...
UITableView的重用机制避免了频繁创建和销毁单元格的开销,使...
Objective-C中,类的实例变量(instance variables)和属性(...
从内存管理的角度来看,block可以作为方法的传入参数是因为b...
WKWebView 是 iOS 开发中用于显示网页内容的组件,它是在 iO...
OC中常用的多线程编程技术: 1. NSThread NSThread是Objecti...