@try@ перехватить блок, не перехватывая внутри исключения

Хорошо, я никогда не видел этого раньше. Вот мой код:

    @try {
        [self.avPlayer removeObserver:self forKeyPath:@"status"];
        [self.avPlayer removeObserver:self forKeyPath:@"rate"];
    } @catch (NSException *exception) {

    } @finally {

    }

Вы можете ясно видеть, у меня есть эти две строки кода в блоке @try. Тем не менее, это все еще разрушает мое приложение. Вот сообщение об ошибке uncaught:

Невозможно удалить наблюдателя для ключевого пути "status" из , поскольку он не зарегистрирован в качестве наблюдателя.

Итак, очень ясно, это вызвано кодом, который я разместил выше. Как, черт возьми, это возможно? Что мне здесь не хватает?

3 ответа

Решение

Чтобы ответить на ваш вопрос о том, почему вы на самом деле не перехватываете исключение, существуют определенные типы исключений, которые не могут быть перехвачены; см. http://www.cocoawithlove.com/2010/05/handling-unhandled-exceptions-and.html для довольно хорошего объяснения того, что это такое, каковы их причины и что с ними делать. Я подозреваю, что исключение, которое фактически выдается, является исключением времени выполнения, с которым вы не можете справиться @try/@catch,

Для сортировки можно попытаться установить точку останова на -[NSException raise] в CoreFoundation или же objc_exception_throw в libobjc.A.dylib и более чем вероятно, что точка останова уловит, что является действительным исключением, и даст вам понять, почему вы его не перехватываете.

Все это, как говорится, gnasher729 ударило по голове о том, как лучше всего справиться с ситуацией такого типа в долгосрочной перспективе (т. gnasher729 кодом, который вы действительно хотите выпустить в мир).

В Objective-C создаются исключения для ошибок программирования. Вы не ловите исключения. Вы исправляете ошибки в своем коде.

Ошибка в вашем коде довольно очевидна: вы пытаетесь удалить наблюдателя, который не существует. Проверьте, действительно ли вы создали наблюдателя или уже удалили его. Вызывайте removeObserver, только если есть наблюдатель.

НЕ используйте TRY / CATCH для этого. Когда есть исключение, дайте ему сбой вашего приложения, выясните, что вызывает исключение, а затем исправьте вашу ошибку.

Этакий "нет ответа", основанный на предыдущих комментариях.

Давайте пропустим философские рассуждения о том, должна ли быть попытка / отлов даже в языке. Почему ваш код не работает?

Вы пытаетесь поймать ловимое исключение, ответ @fullofsquirrels не относится к вашему делу.

Я протестировал ваш код как на OS X, так и на iOS (только для симулятора), как throw, так и за исключением, и оба позволяют вам его поймать. Другими словами, в вашем коде нет ничего плохого, он правильный и должен работать...

Таким образом, есть что-то еще за пределами области кода, который вы разместили, что вызывает проблему. Тебе придется копать.

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

Хорошей охоты!

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