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. Точное число может отличаться для вас.
Ответы
Ответ 1
Этот код выглядит правильно. Похоже, вы столкнулись с ошибкой в компиляторе, что, как правило, имеет место, когда у вас есть авария в конфигурации выпуска, но не отладка. Возможно, вы можете убедиться в этом, включив оптимизации в сборку и тестирование отладки, чтобы определить, создает ли она проблему. Помимо вашего обходного пути, единственное, что вам нужно сделать, это записать ошибку.
Ответ 2
Работала над этим без потери функциональности, используя self.list = self.list.sort()
вместо self.list.sortInPlace()
.
Ответ 3
Это ошибка в Xcode 7.1. Превращение быстрого уровня оптимизации компилятора из быстродействия, чтобы никто не исправил эту проблему для меня.
Ответ 4
Я зарегистрировал ошибку на bugs.swift.org об этом ранее сегодня и получил быстрый ответ от одного из разработчиков, что это действительно проблема с Xcode 7.1. Он отметил, что его резолюция изложена в Примечания к выпуску Xcode 7.2:
Исправлена ошибка в оптимизаторе, которая приводила к сбою на месте сортировки по изменяемым коллекциям. (23081349)
Поэтому использование Xcode 7.2 для компиляции также должно устранить проблему.