在iPhone顶级异常处理程序中显示警报

Mar*_*ith 9 iphone exception objective-c uialertview

我正在尝试在顶级iPhone异常处理程序中显示UIAlertView.处理函数如下所示:

void applicationExceptionHandler(NSException *ex) {
  UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:@"Error"
                                                      message:[ex reason]
                                                      delegate:nil
                                             cancelButtonTitle:@"OK"
                                             otherButtonTitles:nil];
  [alertView show];
}
Run Code Online (Sandbox Code Playgroud)

我在其他地方看到过类似的代码(例如,NSSetUncaughtExceptionHandler没有捕获iPhone上的所有错误).

如果我单步进入调试器,我可以看到异常处理程序被调用,我可以看到当前屏幕变暗,好像它将在它前面显示警报,但什么都没有出现.在调试器之外,应用程序立即退出并返回系统主屏幕.

如果我在applicationDidFinishLaunching中捕获错误并在返回之前显示警报,它确实有效.我假设警报视图永远不会有机会在异常处理程序中显示,因为应用程序正在终止(而不是坐在那里,如果我只是放弃applicationDidFinishLaunching而无所事事).有没有办法让这项工作?

Dav*_*son 9

感谢大家对于benzado,我认为这是一个很棒的通用顶级异常处理程序.我是初学者,所以希望它做得很好,但确实有效:)

在我... appDelegate.m:

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{        
    [window makeKeyAndVisible];

    NSSetUncaughtExceptionHandler(&exceptionHandler);

    return YES;
}

BOOL exceptionAlertDismissed = FALSE;
void exceptionHandler(NSException *exception)
{
    UIAlertView *alert = [[UIAlertView alloc] initWithTitle:@"App Committed Suicide"
        message:@"Oh dear, that wasn't supposed to happen. You will have to restart the application... sorry!"
        delegate:[[UIApplication sharedApplication] delegate] cancelButtonTitle:nil otherButtonTitles:@"That's ok!", @"Erm, bye...", nil];
    [alert show];
    [alert release];

    while (exceptionAlertDismissed == FALSE)
    {
        [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.1]];
    }
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    exceptionAlertDismissed = TRUE;
}
Run Code Online (Sandbox Code Playgroud)

在我的... appDelegate.h:

@interface ...appDelegate : NSObject <UIApplicationDelegate, UIAlertViewDelegate>
...
void exceptionHandler(NSException *exception);
Run Code Online (Sandbox Code Playgroud)


ben*_*ado 8

我不确切知道如何[alertView show]实现,但我想它会对视图层次结构进行一些更改,然后将其自身设置为在下一次通过运行循环时显示警报(查找NSRunLoop).

但是,由于应用程序即将退出,控件不会返回到运行循环,因此永远不会显示警报.这就是为什么你看到屏幕变暗(警报级UIWindow立即被添加show)但警报没有出现(这将在运行循环中发生).

如果包含[[NSRunLoop currentRunLoop] run]在异常处理程序的末尾,则可能会显示警报.

如果您希望在警报完成后让您的应用程序退出,您可以通过runUntilDate:在while循环中调用NSRunLoop来执行此操作,检查标志的值以查看警报是否已被解除.如果有,只需退出处理函数,你就可以了.这意味着您必须在设置该标志的警报上设置委托对象.

如果你想让你的应用继续运行......我不太确定.您可以让运行循环继续用完异常处理程序,但可能会出现错误/奇怪的副作用.所以你可能应该让应用程序退出.此外,如果您确定可以从异常中恢复,那么您应该已经将其捕获到某处.