Я ответил на ваш последний вопрос на эту тему и столкнулся с той же проблемой, что и исключения Carbon HIToolbox, генерируемые IBActions.
Во-первых, отмените все, что я упомянул в моем предыдущем ответе . По некоторым причинам он не работает с IBActions. Я догадываюсь, что HIToolbox ниже в цепочке обработки исключений и получает любые исключения IBAction / GUI, прежде чем NSApplication сможет это сделать. Любая пользовательская функция обработки исключений, которую вы можете зарегистрировать в NSSetUncaughtExceptionHandler()
жизнях (я считаю) в верхней части цепочки.
Вы на правильном пути с NSExceptionHandling:
- Добавьте ExceptionHandling.framework в ваш проект Xcode
#import "ExceptionHandlerDelegate.h"
в ваш AppDelegate.m (или пользовательский класс исключений Singleton)
Внутри AppDelegate.m :
// Very first message sent to class
+ (void)initialize
{
NSExceptionHandler *exceptionHandler = [NSExceptionHandler defaultExceptionHandler];
unsigned int handlingMask = NSLogAndHandleEveryExceptionMask;
[exceptionHandler setExceptionHandlingMask:handlingMask];
[exceptionHandler setDelegate:self];
// ...
}
#pragma mark -
#pragma mark NSExceptionHandler Delegate Methods
// Called 1st: Should NSExceptionHandler log the exception?
- (BOOL)exceptionHandler:(NSExceptionHandler *)sender shouldLogException:(NSException *)exception mask:(unsigned int)aMask
{
// ...log NSException if desired...
return NO; // Changes to YES if NSExceptionHandler should handle logging
}
// Called 2nd: Should NSExceptionHandler handle the exception?
- (BOOL)exceptionHandler:(NSExceptionHandler *)sender shouldHandleException:(NSException *)exception mask:(unsigned int)aMask
{
// ...crash your app here (e.g. [NSApp terminate:self]; )
// ...or handle the NSException and return YES/NO accordingly
return NO; // If app crashed, never gets returned - should crash before that
}
Флаг NSLogAndHandleEveryExceptionMask
указывает NSExceptionHandler перехватывать каждое исключение, которое оно может (я полагаю, только для вашего приложения), независимо от того, где в цепочке исключений оно существует.
Это означает, что блоки @ catch / @ try / @ finally не будут работать, поскольку флаг NSHandleOtherExceptionMask
указывает NSExceptionHandler захватывать «все, что находится ниже» в цепочке обработчиков исключений. Вы можете удалить этот флаг, но тогда HIToolKit, вероятно, снова получит любые исключения IBAction, так как он кажется ниже в указанной цепочке.
Документы Apple содержат информацию о флагах: NSExceptionHandler docs
Таким образом, когда NSException повышается (где-нибудь в вашем приложении AFAIK), и NSLogAndHandleEveryExceptionMask установлен, они вызываются в делегате по порядку:
-exceptionHandler:shouldLogException:mask:
вызывается первым.
-exceptionHandler:shouldHandleException:mask:
называется вторым.
Просто поместите свой «код аварии» во второй метод делегата, и все будет в порядке.
Полезная статья: Понимание исключений и обработчиков в какао
Причина, по которой я думаю, что у вас возникли проблемы с работой делегата NSExceptionHandler, заключается в том, что он НЕ совместим с пользовательским методом, установленным с NSSetUncaughtExceptionHandler()
, что было частью ответа в моем предыдущем вопросе. За Apple :
Класс NSExceptionHandler предоставляет
средства для мониторинга и
отладка исключительных условий в
Программы Objective-C. Это работает
установка специального необученного
обработчик исключений через
NSSetUncaughtExceptionHandler
функция. Следовательно, чтобы использовать
услуги NSExceptionHandler, вы
не должен устанавливать свой собственный кастом
необработанный обработчик исключений.
Это также, вероятно, не работает, когда вы переопределяете метод -reportException:
NSApplication.
И, наконец, нет необходимости использовать @ catch / @ try / @ finally (также часть моего предыдущего ответа). Конфигурирование NSExceptionHandler внутри +initialize
, по-видимому, сразу «включается», в отличие от переопределения метода -reportException:
NSApplication.