在Objective-C中使用时,有时不会调用在Swift类中声明的运算符重载"<"

hel*_*hum 6 operator-overloading objective-c language-interoperability swift

我遇到了一个与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
}
Run Code Online (Sandbox Code Playgroud)

然后将它用于Objective-C方法,如下所示:

if (distance < averageDistance){
    // code
}
Run Code Online (Sandbox Code Playgroud)

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

当使用distance.value == 2375.1842554877021and 运行时averageDistance.value == 75.671794891357421,distance < averageDistance返回时true,Swift运算符重载永远不会被命中,而Objective-C执行条件内的代码.

如果我将有问题的Objective-C方法转换为Swift,它的行为与预期一致,但我担心在我们的应用程序中各种Objective-C方法中存在其他GKDistance比较,可能无法看到Swift运算符重载.

有没有人遇到与Swift/Objective-C互操作性类似的问题,因为它与运营商重载有关?

Mar*_*n R 4

你的

\n\n
public func <(a:GKDistance, b:GKDistance) -> Bool { }\n
Run Code Online (Sandbox Code Playgroud)\n\n

与所有 Swift 运算符 \xe2\x80\x93 一样,\xe2\x80\x93 是顶级函数,并且顶级函数\n不会导出到 Objective-C,请参阅“Swift 类型兼容性”\nin “与 Objective 交互” -C API”

\n\n

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

\n\n\n\n

因此在

\n\n
if (distance < averageDistance) {\n    // code\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

只是比较两个指针distance,如果 by 指向的对象驻留在比 by 指向的对象指针更低的内存地址中,则条件为 true averageDistance(这显然不是您想要的)。

\n\n

您可以做的是在您的类中实现一种compare:方法,\n类似于 或NSString之一NSNumber

\n\n

另请注意,对于NSObject子类,您应该覆盖\nisEqual:而不是实现==, Compare

\n\n\n