Сбой при приведении объекта внутрь для цикла только в режиме выпуска


Я использую метод с петлей for внутри:

func filter (array: NSArray) -> NSMutableArray {
    var filteredArray: NSMutableArray = NSMutableArray()
    for objects in array as [MyObject] { // this line crash only on release mode
        // TODO
    }
    return filteredArray
}

Когда это режим отладки, он работает нормально, но когда я переключаюсь в режим выпуска, он разбивается на линии:

for objects in array as [MyObject]{

Когда я изменяю метод на этот (без приведения внутри цикла), он не будет сбоить при отладке и в режиме выпуска:

func filter (array: [MyObject]) -> NSMutableArray {
    var filteredArray: NSMutableArray = NSMutableArray()
    for objects in array {
        // TODO
    }
    return filteredArray
}

Могут ли некоторые объяснить, почему?

1 2

1 ответ:

Трудно сказать, не зная, что на самом деле находится внутри NSArray. Я предлагаю установить точку останова и проверить содержимое переменной array.

Однако причина заключается в том, что оператор as не выполняет приведение, потому что по крайней мере один элемент в array не является экземпляром (подклассом) MyObject. Я бы защитил этот код с помощью необязательного приведения, хотя это пропустило бы весь цикл for, Если приведение завершится неудачей.

func filter (array: NSArray) -> NSMutableArray {
    var filteredArray: NSMutableArray = NSMutableArray()
    if let array = array as? [MyObject] {
        for objects in array as [MyObject] { // this line crash only on release mode
            // TODO
        }
    }
    return filteredArray
}

Если вы уверены, что массив содержит MyObject затем я решил бы проблему в коде, который вызывает эту функцию, используя swift-массив вместо NSArray, чтобы избежать проблем приведения, но, конечно, это зависит от вашего фактического кода - так что это не решение, которое может работать во всех случаях.

Обновление это решение также может лучше решить вашу проблему, если у вас есть массив с элементами смешанных типов, но вы заинтересованы в обработке только тех, которые имеют MyObject тип:

func filter (array: NSArray) -> NSMutableArray {
    var filteredArray: NSMutableArray = NSMutableArray()
    for element in array {
        if let element = element as? MyObject {
            // TODO
        }
    }
    return filteredArray
}

В разница в том, что вместо того, чтобы пытаться привести весь массив, приведение выполняется для каждого элемента.