【问题标题】:Swift 2.1 Error sorting in place, only on release buildsSwift 2.1 错误排序,仅在发布版本上
【发布时间】:2016-01-31 09:05:54
【问题描述】:

我开始在下面的代码中收到 sort lamdba 的崩溃报告,下面灰色框中的第三行:

private func fixOverlaps(inout blocks: [TimeBlock], maxOverlaps: Int? = nil) {
    blocks.sortInPlace { a,b in
        if a.startTime < b.startTime {
            return true
        } else if a.startTime == b.startTime && a.endTime < b.endTime {
            return true
        }
        return false
    }
...

请注意,在 XCode 的调试版本中不会发生崩溃。只有 App Store 和 Ad Hoc 存档会崩溃,并且只有在阻止列表的长度在数百个时才会崩溃。

我把代码修改成这个,问题就解决了:

private func fixOverlaps(inout blocks: [TimeBlock], maxOverlaps: Int? = nil) {
    blocks = blocks.sort { a,b in
        if a.startTime < b.startTime {
            return true
        } else if a.startTime == b.startTime && a.endTime < b.endTime {
            return true
        }
        return false
    }
...

关于如何使用 inout 或 sortInPlace,我是否遗漏了什么?我可以尝试做一个演示。它在多个版本的 iOS (8/9) 和 Swift 2.1 上。

编辑--------

好的,这是一个崩溃的最小版本。原来inout是一条红鲱鱼。如果你在 XCode 7.1 中开始一个新的单视图项目,你可以用这个替换视图控制器:

class ViewController: UIViewController {

override func viewDidLoad() {
    super.viewDidLoad()
    // Do any additional setup after loading the view, typically from a nib.

    var blocks = [TimeBlock]()
    for var i in 0...20 { //Works if you put in a small number like 8
        let t = TimeBlock()
        t.start = Int(arc4random_uniform(1000)) //Get some random numbers so the sort has to do some work
        t.end = Int(arc4random_uniform(1000))
        blocks.append(t)
    }

    blocks.sortInPlace { a,b in
        if a.start > b.start {
            return true
        }
        return false
    }

    print("done") //Gets here on debug, not release
}

class TimeBlock {
    var start = 0
    var end = 0
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}


}

所以在发布时运行它,如果您在 17 左右结束循环但在 20 时崩溃,您应该会看到它打印“完成”。确切的数字可能与您不同。

【问题讨论】:

  • 绝对有一位要向 Apple 报告:bugreport.apple.com
  • 与核心问题无关的示例代码清理:if 中的sortInPlace 是不必要的,因为&gt; 已经给了你一个布尔值。你可以写{ a,b in return a.start &gt; b.start }。更简单的是,您可以使用{ $0.start &gt; $1.start },因为使用$0 会使返回隐含。
  • @PaulCantrell 末世呢?这会自己清理吗?
  • @Carlos 不,我在 EDIT 行下简化了崩溃的最小版本中的代码。
  • 我不敢相信谷歌搜索“sortInPlace crash with 17 items”实际上找到了结果。立即归档雷达。

标签: ios swift compiler-errors


【解决方案1】:

我今天早些时候就此事记录了bug on bugs.swift.org,并收到了一位开发人员的及时回复,说这确实是 Xcode 7.1 的问题。他指出,Xcode 7.2 Release Notes 中概述了它的解决方案:

已修复优化器中的一个错误,该错误会导致对可变集合进行就地排序崩溃。 (23081349)

所以使用 Xcode 7.2 编译应该也能解决这个问题。

【讨论】:

  • 太棒了。很高兴这很有帮助。快疯了。
【解决方案2】:

通过使用self.list = self.list.sort() 而不是self.list.sortInPlace() 解决了这个问题而不会丢失功能。

【讨论】:

    【解决方案3】:

    此代码看起来正确。听起来您在编译器中遇到了一个错误,这通常是您在发布配置中崩溃但没有调试的情况。您也许可以通过在调试构建和测试中启用优化来验证这一点,以查看它是否会产生问题。除了您的解决方法之外,您唯一需要做的就是file a bug

    【讨论】:

    • 我会在几分钟后粘贴一个工作(不管你怎么称呼它)演示。我已经在一个新项目中复制了它。
    • 好了,测试一下。
    【解决方案4】:

    这是 Xcode 7.1 中的一个错误。将 swift 编译器优化级别从 fast 变为 none 为我解决了这个问题。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-15
      • 1970-01-01
      • 2014-10-16
      • 2012-01-05
      • 1970-01-01
      • 1970-01-01
      • 2021-05-08
      相关资源
      最近更新 更多