Почему этот код падает в распределенном приложении, но работает в отладчике?

У меня есть простой код, который выполняется, и в случае его сбоя я хочу перехватить исключение, чтобы приложение не зависало.

@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 памяти).

В режиме выпуска он не создает эти средства защиты, поэтому при записи за пределами выделенной памяти могут происходить плохие вещи (например, сбои).

Другие вопросы по тегам