@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, так и за исключением, и оба позволяют вам его поймать. Другими словами, в вашем коде нет ничего плохого, он правильный и должен работать...
Таким образом, есть что-то еще за пределами области кода, который вы разместили, что вызывает проблему. Тебе придется копать.
В качестве отправной точки вы можете посмотреть на трассировку стека и посмотреть, предлагает ли это какую-либо подсказку относительно причины.
Хорошей охоты!