2

我在 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函数移动到同一个文件中,并且不再发生崩溃。但我宁愿在正确的模块中使用该功能。

4

0 回答 0