6

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

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

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

当使用distance.value == 2375.1842554877021and运行时averageDistance.value == 75.671794891357421,return 永远不会遇到 Swift 运算符重载,并且 Objective-C 会执行条件内的代码。distance < averageDistancetrue

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

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

4

1 回答 1

4

您的

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

与所有 Swift 运算符一样,它是一个顶级函数,并且顶级函数不会导出到 Objective-C,请参阅“与 Objective-C API 交互”中的“Swift 类型兼容性”

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

因此在

if (distance < averageDistance) {
    // code
}

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

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

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

于 2016-06-07T14:46:55.567 回答