Как вы реализуете глобальную обработку исключений iPhone?
У меня есть один сбой в приложении для iPhone, который вызывает NSException. Отчеты о сбоях совершенно неоднозначны, когда ошибка и что именно вызывает ее. Есть ли у меня разумный способ установить обработчик исключения верхнего уровня где-нибудь, чтобы узнать, что его вызывает? Я не могу воспроизвести проблему самостоятельно, но некоторые из моих бета-пользователей, безусловно, могут.
Какой умный способ справиться с проблемой такого рода?
- Есть ли реальное решение для отладки приложений cordova
- Что такое трассировка стека, и как я могу использовать ее для отладки ошибок моего приложения?
- Как я могу отладить мое приложение Meteor с помощью WebStorm IDE?
- Где появляется сообщение System.Diagnostics.Debug.Write?
- Как я могу узнать, что делает мой запрос на активные запросы?
- R строк строки сценария при ошибке?
- Как отлаживать скрипт перезаписи htaccess
- Как определить, было ли приложение .NET скомпилировано в режиме DEBUG или RELEASE?
- Как отладить многопоточное приложение в IntelliJ?
- Отслеживать все вызовы метода ObjC?
- Как я могу сделать что-то, что ловит все «необработанные» исключения в приложении WinForms?
- Как включить номера строк в трассировку стека без pdb?
- Запуск приложения в GDB до тех пор, пока не произойдет исключение
Если вы планируете делать это самостоятельно, вы можете использовать один из этих подходов
Approach1:
void onUncaughtException(NSException* exception) { //save exception details } - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { NSSetUncaughtExceptionHandler(&onUncaughtException); //Add coding to find if any exception has occurred from saved details if so send it to server or ask user to comment on the issue. //Rest of the coding }
Approach2:
void onUncaughtException(NSException* exception) { //Save exception details } int main(int argc, char *argv[]) { @autoreleasepool { NSSetUncaughtExceptionHandler(&onUncaughtException); return UIApplicationMain(argc, argv, nil, NSStringFromClass([SGGI_AppDelegate class])); } } -(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { //Add coding to find if any exception has occurred from saved details if so send it to server or ask user to comment on the issue. //Rest of the coding }
Approcach3:
int main(int argc, char *argv[]) { @autoreleasepool { @try { return UIApplicationMain(argc, argv, nil, NSStringFromClass([SGGI_AppDelegate class])); } @catch (NSException *exception) { //Save the exception } @finally { } } } -(BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { //Add coding to find if any exception has occurred from saved details if so send it to server or ask user to comment on the issue. //Rest of the coding }
Заметка:
-
В моей перспективе не пытайтесь отправить данные об исключениях на сервер во время сбоя, отправьте его, когда он снова запустит приложение.
-
Если вы собираетесь использовать NSUserDefaults для сохранения сведений об исключении, вам необходимо синхронизировать их во время сбоя, иначе он не будет сохраняться.
Следующий fragment кода выполняет задание.
- (void)applicationWillTerminate:(UIApplication *)application { [[NSUserDefaults standardUserDefaults]synchronize]; }
- Если вы предпочитаете сохранять его на sqlite db, тогда он не нуждается в том, чтобы называть что-либо, чтобы сохраняться в момент сбоя
В XCode вы всегда должны устанавливать глобальную objc_exception_throw
останова для objc_exception_throw
. Затем вы (обычно) получаете гораздо более значимую трассировку стека относительно того, что на самом деле пытается выбросить исключение.
Вы все равно можете получать исключения, которые возникают из кода таймера или других мест без вашего собственного кода в любом месте трассировки, но если вы посмотрите на цепочку методов, вы обычно можете определить, что такое исключение (например, если отправлено уведомление, отсутствует).
Вы пробовали NSSetUncaughtExceptionHandler
?
Другим вариантом отслеживания отчетов о сбоях является правдоподобный CrashReporter , открытый исходный код, который автоматически отправляет вам отчеты о сбоях из поля.
Существует также CrashReporterDemo , еще один вариант с открытым исходным кодом, который представляет собой комбинацию правдоподобного CrashReporter и некоторого кода сервера для лучшего отслеживания отчетов о сбоях.
И, наконец, есть MacDevCrashReporter , служба, которая, похоже, имеет сходство с iOSExceptional.com, в другом ответе. Я понятия не имею, каковы условия их обслуживания, поскольку я не подписался на бета-версию. Определенно стоит проверить, прежде чем проникать слишком глубоко.
Проверьте Критерий . Это выше и выше того, о чем вы просите здесь, что позволяет вам получать эту информацию для всех пользователей, использующих ваше приложение, чтобы вы могли увидеть свой собственный сбой.
Вы также можете загрузить DYSM для своей конкретной сборки, и она автоматически символизирует крах для вас на своем веб-сайте. Это должно предоставить вам самую четкую трассировку стека без подключения к отладчику.
Вы также можете захотеть убедиться, что вы настроены на перерыв в исключениях Objetive-C. В Xcode 4 на вкладке точек останова вы можете добавить исключение Breakpoint Exception, которое разбивается на оба варианта C ++ и Obj-C. Без этого большинство трассировок стека за выброшенные исключения довольно бесполезны.
Удачи!