我在Swift中创建了一个中缀运算符来比较两个可选的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
函数移动到同一个文件中,不再发生崩溃。但我宁愿在正确的模块中使用该功能。