Почему этот код падает в распределенном приложении, но работает в отладчике?
У меня есть простой код, который выполняется, и в случае его сбоя я хочу перехватить исключение, чтобы приложение не зависало.
@try {
x = [self try_doMyWork:Param];
} @catch (NSException* e) {
NSLog(@"Exception");
}
Хотя этот код работает в режиме отладки и перехватывает исключение (это простой индекс за концом массива), он падает в распределенных приложениях на iPhone.
Почему это так и как я могу гарантировать, что он также работает в распределенных приложениях?
2 ответа
Неперехваченные исключения уровня приложения - только одна из причин сбоев. Сигналы BSD, такие как EXC_BAD_ACCESS, также могут вызывать сбои - и обнаружение исключений NSE не предотвратит их.
Невозможно сказать, что такое конкретный сбой, не зная подробностей try_doMyWork:, но я думаю, что наиболее частой причиной сбоев на уровне C (а не на уровне Objective-C) являются проблемы управления памятью - попытка записи или чтения чего-либо Ваше приложение не должно иметь доступ. Наиболее вероятное объяснение состоит в том, что исключение, которое вы видите в отладке, не совпадает с ошибкой, которую вы видите в дистрибутиве.
В режиме отладки менеджер кучи может распределять объекты с буферными зонами до и после них (называемые охранниками) и заполнять эти охранники известными значениями (например, 0x7F). Он делает это так, чтобы он мог проверить эти средства защиты при освобождении памяти и определить, записали ли вы данные за пределы выделенной памяти (или до ее начала). Таким образом, он может сообщить вам, что в вашем коде есть ошибка (scribbler памяти).
В режиме выпуска он не создает эти средства защиты, поэтому при записи за пределами выделенной памяти могут происходить плохие вещи (например, сбои).