我在 Swift 中创建了一个中缀运算符来比较两个 Optional、Equatable 值(我通常需要这样做):
infix operator ==? { precedence 130 }
public func ==? <T: Equatable> (lhs: T?, rhs: T?) -> Bool {
if let left = lhs, right = rhs {
return left == right
}
if lhs == nil && rhs == nil {
return true
}
return false
}
很简单。
我有一个User
使用这个中缀运算符的类型,作为它Equatable
符合以下条件的一部分==
:
public func ==(lhs: User, rhs: User) -> Bool {
if lhs.id != rhs.id {
return false
}
return
lhs.firstName ==? rhs.firstName &&
lhs.lastName ==? rhs.lastName &&
lhs.photoURL ==? rhs.photoURL &&
lhs.orgID == rhs.orgID
}
如您所见,我有一些可选参数需要使用中缀运算符相互比较。如果我使用配置构建debug
,一切正常。但是,如果我使用配置进行构建release
,我会遇到此崩溃(通过 Fabric/Crashlytics 报告):
EXC_BAD_ACCESS KERN_INVALID_ADDRESS at 0x4000000000000000
堆栈跟踪很长,但相关的崩溃发生在这里:
libswiftCore.dylib swift_unknownRetain + 16
User.swift line 24 function signature specialization <Arg[0] = Exploded, Arg[1] = Exploded> of static TransportLayer.== infix (TransportLayer.User, TransportLayer.User) -> Swift.Bool
line 24
直接对应public func ==(lhs: User, rhs: User) -> Bool {
。如果我删除中缀运算符==?
,则不会发生崩溃。
如果我将中缀运算符替换为顶级函数public func ==(lhs: User, rhs: User) -> Bool {...}
(与 完全相同的实现),仍然==?
会发生崩溃。所以它并不特定于中缀运算符。
同样,这只发生在 Swift 1.2 下的发布版本上。我不能使用 Swift 2,因为它不是测试版,所以请不要将其作为答案提交。
更新
问题似乎与模块有关。中缀运算符和顶级函数在一个名为 的单独模块中定义Utilities
,我将其导入到User.swift
文件中。我尝试将isEqual
函数移动到同一个文件中,并且不再发生崩溃。但我宁愿在正确的模块中使用该功能。