【发布时间】: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是不必要的,因为>已经给了你一个布尔值。你可以写{ a,b in return a.start > b.start }。更简单的是,您可以使用{ $0.start > $1.start },因为使用$0会使返回隐含。 -
@PaulCantrell 末世呢?这会自己清理吗?
-
@Carlos 不,我在 EDIT 行下简化了崩溃的最小版本中的代码。
-
我不敢相信谷歌搜索“sortInPlace crash with 17 items”实际上找到了结果。立即归档雷达。
标签: ios swift compiler-errors