Ответ 1
Удивительно, но я проследил это, главным образом, удалив код в больших образцах, пока я не дошел до этого (это контроллер вида):
class LessonListController: UIViewController {
var terms : [Term]
// var terms : NSArray
init(terms data:NSArray) {
let arr = data.sortedArrayUsingDescriptors([NSSortDescriptor(key: "lessonSection", ascending: true)])
self.terms = arr as! [Term]
// self.terms = arr
super.init(nibName:"LessonList", bundle:nil)
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
@IBAction func doDismiss(sender: AnyObject) {
self.dismissViewControllerAnimated(true, completion: nil)
}
}
Если (в сборке Release) мы представляем этот контроллер представления, а затем увольняем его, мы выходим из командной строки dealloc, что доказывает мою теорию о том, что это проблема управления памятью.
Выделив код, я смог попробовать различные альтернативы. Ясно, что проблема заключается в свойстве var terms : [Term]
(потому что единственное, что Swift делает под капотом в dealloc
, выпускает этот массив). Значение этого свойства, как вы можете видеть в моем init
, представляет собой NSArray, который появился из Cocoa (thru sortedArrayUsingDescriptors
) и был перенесен в массив Swift. Судом и ошибкой я обнаружил:
-
Если мы изменим реализацию так, чтобы это свойство было NSArray (см. альтернативные строки с комментариями), мы не сбой.
-
Или, если мы не сортируем (так что этот NSArray не приходит из Cocoa), мы не сбой.
-
Или (дождитесь его), если мы заменим
self.terms = arr as! [Term]
наself.terms = arr as NSArray as! [Term]
, мы не сработаем!
Но эта третья альтернатива - обходной путь. Я просмотрел весь свой код во всех своих приложениях, ищущих приведения as! [SomeType]
и заменив их на as NSArray as [SomeType]
, и все мои сбои исчезли.
Моя теория заключается в том, что что-то не так с управлением памятью Swift в оптимизированной версии релиза только в очень конкретной ситуации, когда NSArray прибывает из Cocoa и соединяется для нас с [AnyObject]
, прежде чем наш код сможет ухватиться из этого. Такой NSArray не пересекает мост должным образом. Но, перейдя в NSArray, а затем обратно вниз до конкретного массива [SomeType]
Swift, проблема решена.
Естественно, я предполагаю, что, когда Apple это выяснит, они исправит его, и тогда мы можем прекратить использовать этот обходной путь. Но до тех пор мои приложения снова запускаются в сборке Release.