【问题标题】:How can I make my Objective-C class conform to Swift's `Equatable` protocol?如何让我的 Objective-C 类符合 Swift 的 `Equatable` 协议?
【发布时间】:2015-09-04 21:31:22
【问题描述】:

我有一个 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 没有被这样注释,它不可能被如此注释。

标签: objective-c swift protocols language-interoperability


【解决方案1】:

如果你的 Objective C 类是一个 NSObject,实现 isEqual:

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

这对我来说适用于 Array.index(of: myobject) 和 == 比较。 NSObject 已经是 Equatable 了,所以使用 Swift 扩展是行不通的。

【讨论】:

    【解决方案2】:

    首先,在 Swift 中为您的类编写一个自定义的 == 运算符函数。

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

    或许,例如:

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

    现在你的类符合Equatable,这是 Swift 特有的。您不能在 Objective-C 端执行此操作,因为您无法为 Objective-C 编写自定义运算符。

    【讨论】:

    • @Yerk 阅读答案的最后一行。对于 Objective-C,你不能这样做。 Swift 的Equatable 协议需要一个自定义运算符(特别是==),而Objective-C 没有办法做到这一点。也许更重要的是,无论如何,您都应该尝试为 Objective-C 执行此操作。 Objective-C 的 == 等效于 Swift 的 === 用于对象引用。我们不应该改变 30 年前的 Objective-C 行为......
    • 另外,Equatable 协议没有被定义为@objc 协议,因此该协议根本不能在 Objective-C 中使用。 Equatable 是一个纯粹的 Swift 协议。使 Objective-C 类符合该协议的方法是从 Swift 中扩展该类。没有什么是有意义的。您实际上是在问“如何在 Objective-C 中覆盖 == 的默认行为?”
    • @Alix 没有。 Swift 的=== 大致相当于Objective-C 的==。这是一个参考比较。
    • 所以在 Objective-C 中,如果我想测试 2 个对象之间的相等性,我应该怎么做?
    • @Honey [obj1 isEqual:obj2];。一些类,例如NSString,还有其他方法,例如[str1 isEqualToString:str2];。在这种特定情况下,isEqualToString:isEqual: 是等价的。并且所有对象都从NSObject继承isEqual:,但默认实现只是==引用比较。
    猜你喜欢
    • 2015-02-05
    • 1970-01-01
    • 2016-09-29
    • 2020-12-04
    • 1970-01-01
    • 1970-01-01
    • 2017-06-27
    • 1970-01-01
    相关资源
    最近更新 更多