【问题标题】:Operator overload "<" declared in Swift class is sometimes not called when used in Objective-C在 Swift 类中声明的运算符重载“<”在 Objective-C 中使用时有时不会被调用
【发布时间】:2016-06-07 14:28:19
【问题描述】:

我遇到了一个与 Swift/Objective-C 互操作性相关的奇怪问题。情况是这样的:

我有一个用 Swift 编写的 @objc public class GKDistance:NSObject,NSCoding,Comparable。为了比较距离,我为&lt; 添加了一个运算符重载,如下所示:

public func <(a:GKDistance, b:GKDistance) -> Bool {
    return a.value < b.value
}

public func ==(a:GKDistance, b:GKDistance) -> Bool {
    return a.value == b.value
}

然后在 Objective-C 方法中使用,如下所示:

if (distance < averageDistance){
    // code
}

当调用 Objective-C 方法时,我可以在 &lt; 方法中添加 print() 语句和断点,以确认何时使用运算符重载。在一种情况下,它神秘地跳过了 Swift 中定义的运算符重载,并在两个 GKDistance 对象之间使用了常规的 Objective-C 比较器。

当使用distance.value == 2375.1842554877021averageDistance.value == 75.671794891357421 运行时,distance &lt; averageDistance 返回true,不会遇到 Swift 运算符重载,并且 Objective-C 会执行条件内的代码。

如果我将相关的 Objective-C 方法转换为 Swift,它会按预期运行,但我担心在我们的应用程序中的各种 Objective-C 方法中还有其他 GKDistance 比较可能无法看到 Swift 运算符超载。

有没有人遇到过与运算符重载有关的 Swift/Objective-C 互操作性的类似问题?

【问题讨论】:

    标签: objective-c swift operator-overloading language-interoperability


    【解决方案1】:

    你的

    public func <(a:GKDistance, b:GKDistance) -> Bool { }
    

    是——就像所有 Swift 运算符一样—— 顶级函数,和顶级函数 未导出到 Objective-C,请参阅“Swift 类型兼容性” 在"Interacting with Objective-C APIs"

    另请注意,您不能覆盖 (Objective-)C 中的运算符(如 &lt;),参见例如

    因此在

    if (distance < averageDistance) {
        // code
    }
    

    只比较两个指针,如果条件为真 distance 指向的对象位于较低的内存地址 比averageDistance 指向的对象指针(这显然是 不是你想要的)。

    你可以做的是在你的类中实现一个compare: 方法, 类似于NSStringNSNumber 之一。

    另请注意,对于 NSObject 子类,您应该覆盖 isEqual:而不是实现==,比较

    【讨论】:

    • 我认为您没有回答这个问题。虽然我知道您不能在 Objective-C 中重载运算符(如
    • @ColinPhillips: if (distance &lt; averageDistance) 不调用任何函数,&lt; 运算符是 C 中“内置”的,例如比较stackoverflow.com/questions/3417413/operator-overloading-in-c。那是两个指针,它们被比较。
    • @ColinPhillips:我添加了一些参考资料。
    • 这是正确答案。 Objective-C 将无法访问 Swift 类中指定的运算符重载,并且 Objective-C 代码将 100% 的时间比较指针。
    • 感谢@MartinR 的澄清 - 我对你的回答投了赞成票。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-07-19
    相关资源
    最近更新 更多