5

我有一个类,如果存在以下情况,我想将用户重定向到错误页面:未捕获的异常、捕获的异常或自定义异常。我还想关闭一封错误电子邮件。(以便我收到通知)。

我无法访问此类中的当前视图控制器(在未捕获异常的情况下)。因为它是由委托侦听器触发的onUncaughtException(NSException* exception)

如何访问当前的视图控制器,或者如果失败,以模式将用户重定向到错误视图控制器?

#import "ErrorHelper.h"
#import "ErrorViewController.h"
#import "Global.h"
#import "AppDelegate.h"

@implementation ErrorHelper


+(void) handleUncaughtError:(NSException*) exception
{
    NSLog(@"Uncaught exception occurred!");
    
    [self sendErrorEmailIfAppropriate:exception :nil];
    [self redirectToErrorPage];
}

+(void) handleCaughtError:(NSException*) exception
{
    NSLog(@"Error caught!!");
    
    [self sendErrorEmailIfAppropriate:exception :nil];
    [self redirectToErrorPage];
}

+(void) handleCaughtCustomError:(NSString*) ref :(NSString*) details
{
    NSLog(@"Custom error caught!!");
    //can do conditional branching on @ref, to do appropriate action.
    
    [self sendErrorEmailIfAppropriate:nil :details];
    [self redirectToErrorPage];
    
    
}

+(void) sendErrorEmailIfAppropriate:(NSException*) exception :(NSString*)details
{
    if([[Global get] isInTestMode] || [[Global get] isInLiveMode]) {
        bool isCustomException = details != nil;
        
    }
}

+(void) redirectToErrorPage
{
    /*Try redirect user to error page
    E.G:
     -There's been an error, our App Dev team will try and resolve the issue for you
     -Regards -Dev team
     
    */
    AppDelegate *appDelegate = [[UIApplication sharedApplication] delegate];
    
}

@结尾

4

5 回答 5

4

您应该假设 Cocoa 异常是不可恢复的。不要扔掉它们,不要将它们添加到您的程序中。(在 C++ 中使用异常很好,尽管在这方面混合 C++ 和 ObjC 可能是不安全的,因为 ObjC 并不是为这种控制流或展开时的清理而设计的)。

有一些奇怪的 ObjC API 会抛出异常,您可以从中恢复。如果可能,请使用不会抛出的替代方案。如果您必须在这种情况下尝试/捕获,那么您应该使您的处理程序尽可能位于调用站点的本地。假设未捕获的 ObjC 异常或被高级处理程序捕获的异常是不可恢复的。

现在,因为您捕获的异常是调用站点的本地异常,您可以轻松添加逻辑以将错误传播到视图控制器或返回到事件循环(例如 AlertView)。是的,在这种情况下,您可能会引入一些错误输出参数或返回值。

电子邮件是一个单独的问题。

于 2012-11-12T01:12:53.470 回答
1

如果你真的想实现这一点,你可以尝试类似的东西,

1 - 将当前屏幕对象存储在 viewDidAppear 方法中的 UIViewController 对象(应用程序级别)中。

2 - 这将为您提供应用程序中的当前屏幕。

(我没有测试过这个,但我想应该可以)

3 - 发送通知(bcoz 现在你有当前的屏幕实例)。

4 - 显示您的错误页面

于 2012-11-12T09:57:43.483 回答
1

在 main.m 类中使用 -

NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
int retVal = -1;
@try {
    retVal = UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
}
@catch (NSException* exception) {
    NSLog(@"Uncaught exception: %@", exception.description);
    --Send email here or Open ur link or Wat ever action u'd like to do or Use the Error helper class of urs HERE--
}
[pool release];
return retVal;

这个想法是,由于任何对象导致的所有崩溃最终都将通过 main.m 类,这是在整个 App 生命周期中查看崩溃的最佳位置。

于 2012-11-12T10:22:43.423 回答
1

有关如何安装全局异常处理程序的信息,请参阅在 iPhone 顶级异常处理程序中显示警报.. 但正如贾斯汀所说,异常应被视为“致命”——您甚至可以打开一个 url/显示一个 webview

但之后不要尝试恢复正常操作

于 2012-11-12T10:35:33.937 回答
1

我试过这个:exception_handler它的工作!只需编写您的电子邮件发送代码而不是警报视图。

- (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;
}

在界面中,

@interface ...appDelegate : NSObject <UIApplicationDelegate, UIAlertViewDelegate>
...
void exceptionHandler(NSException *exception);
于 2012-11-18T08:13:39.327 回答