Swift 2.1错误排序到位,仅在发布版本上

我开始在下面的代码中获取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的多个版本。

编辑 – – – – – – – – – –

好的,这是一个崩溃的最小版本。 原来这是一个红鲱鱼。 如果在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。确切的数字可能会有所不同。

此代码看起来正确。 听起来你遇到了编译器中的一个错误,当你在发布配置中崩溃而不是调试时通常就是这种情况。 您可以通过在调试构建和测试中启用优化来validation这一点,以确定它是否会产生问题。 除了您的解决方法之外,您需要做的唯一其他事情是提交错误 。

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

这是Xcode 7.1中的一个错误。 将swift编译器优化级别从快速转为无,为我解决了这个问题。

我今天早些时候在bugs.swift.org上记录了一个关于此问题的错误,并收到一位开发人员的快速回复,这确实是Xcode 7.1的一个问题。 他指出其解决方案在Xcode 7.2发行说明中概述:

优化器中的错误已得到修复,导致可变集合的就地排序崩溃。 (23081349)

所以使用Xcode 7.2进行编译也应该解决问题。