我该如何使我的Objective-C类符合Swift的`Equatable`协议?

6

我有一个Objective-C类(它恰好是一个按钮,但这不重要),在我的项目的另一个部分,我有一个这些按钮的数组,并且我想使用find()方法获取按钮的索引。就像这样:

func doSomethingWithThisButtonIndex(index:Int)
{
    let buttons = [firstButton, secondButton, thirdButton]
    if index == find(buttons, firstButton)
    {
        // we've selected the first button
    }
}

但我遇到了一个问题

类型“ImplicitlyUnwrappedOptional”不符合协议“Equatable”

好的,那么让我们转到Objective-C并让ButtonThing实现<Equatable>。但它无法识别。

那么我该怎么办呢? 目前我正在绕过它进行构建,强制将数组作为NSArray并使用indexOfObject。但这很丑陋。而且令人沮丧。


如果我的回答不能满足您的需求,那么唯一的其他答案就是“不可能”。除非协议被注释为@objc或者你从Swift端进行操作,否则你无法使一个Objective-C类符合Swift协议。Equatable没有被注释为这样,而且它不可能被注释为这样。 - nhgrif
2个回答

8

首先,在 Swift 中编写一个自定义的 == 操作符函数来处理您的类。

其次,在 Swift 中编写一个类扩展,添加 Equatable 协议的一致性。

例如:

func == (lhs: YourClass, rhs: YourClass) -> Bool {
    // whatever logic necessary to determine whether they are equal
    return lhs === rhs
}

extension YourClass: Equatable {}

现在你的类符合 Swift 特有的 Equatable 协议。在 Objective-C 中,你无法编写自定义操作符,因此不能在 Objective-C 端执行此操作。


1
@Yerk 读取答案的最后一行。你不能在Objective-C中这样做。Swift的Equatable协议需要一个自定义运算符(具体来说,是==),而在Objective-C中无法实现这一点。或许更重要的是,你本来就不应该试图在Objective-C中这样做。Objective-C的==与Swift的对象引用的===是等价的。我们不应该改变那个已经存在30年的Objective-C行为... - nhgrif
1
此外,Equatable协议并未被定义为@objc协议,因此该协议无法从Objective-C中使用。 Equatable是一个纯Swift协议。使Objective-C类符合此协议的方法是通过在Swift中扩展该类。没有其他方法能够实现这一点。您实际上正在问“如何在Objective-C中覆盖==的默认行为?” - nhgrif
@Alix 不是这样的,Swift 中的 === 大致相当于 Objective-C 中的 ==。它是一个引用比较操作符。 - nhgrif
实现 isEqual: 方法。在 Objective-C 中无法重载运算符(请注意此答案的最后一句话)。 - nhgrif
好的...你的意思是就像你自己编写的任何其他方法一样,编写一个名为isEqual:并返回布尔值的方法。这很简单。因此,基本上在Swift中,您以更明确的方式提到它,并且还可以使用更可读的方式即== - mfaani
显示剩余3条评论

2

如果你的 Objective C 类是 NSObject 类型,那么请实现 isEqual: 方法。

- (BOOL)isEqual:(_Nullable id)other;

这对于Array.index(of: myobject)和==比较对我很有用。NSObject已经实现了Equatable,因此使用Swift扩展是无效的。


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