Ios 从项目中的任何位置引发异常

Ios 从项目中的任何位置引发异常,ios,objective-c,xcode,Ios,Objective C,Xcode,我想在代码中任何地方发生异常时显示警报。 不包含可能引发异常的代码 每次发生异常时,它都会在主类中显示错误。从那里可以处理吗? 这是使用以下命令引发异常的正常方式: @try { // code that may throw exception } @catch (NSException * e) { // show alert } @finally { } 导航到Xcode中的断点面板,单击左下角的“加号”按钮添加新断点,然后执行以下操作: 构建并运行您的项目,

我想在代码中任何地方发生异常时显示警报。

不包含可能引发异常的代码

每次发生异常时,它都会在主类中显示错误。从那里可以处理吗?

这是使用以下命令引发异常的正常方式:

@try {
 // code that may throw exception

 }
 @catch (NSException * e) {
  // show alert
 }
 @finally {     
 }

导航到Xcode中的断点面板,单击左下角的“加号”按钮添加新断点,然后执行以下操作:


构建并运行您的项目,Xcode将把您带到异常抛出的地方。

然而,我发现了一个有效的解决方法——创建我自己的异常处理程序(这对于其他原因也很有用)。首先,创建一个处理错误的函数,并将其输出到控制台(以及您想对其执行的任何其他操作)

接下来,将异常处理程序添加到应用程序委托:

    - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
     {   
        NSSetUncaughtExceptionHandler(&uncaughtExceptionHandler);
         // Normal launch stuff
     }
如果这不起作用,那么只有两个可能的原因:

某些内容正在覆盖您的NSSetUncaughtExceptionHandler调用(整个应用程序只能有一个处理程序)。例如,一些第三方库设置了自己的uncaughtExceptionHandler。因此,请尝试在didFinishLaunchingWithOptions功能结束时设置它(或有选择地禁用第三方库)。或者更好的是,在NSSetUncaughtExceptionHandler上设置一个符号断点,以快速查看是谁在调用它。您可能想做的是修改当前的一个,而不是添加另一个。
您实际上没有遇到异常(例如,EXC_BAD_ACCESS不是异常)

我在main.m中添加了异常处理代码

 int main(int argc, char * argv[]) {
            @try {
                @autoreleasepool {
                 return UIApplicationMain(argc, argv, nil, NSStringFrom

Class([AppDelegate class]));
            }

        } @catch (NSException *exception) {

            NSLog(@"exception");
        }
    }

现在可以工作了。

如果我正确理解了这个问题,那么您似乎正在寻找一种处理代码中可能由用户操作(例如无效数据、表单中缺少字段等)导致的错误的好方法

最好的方法是使用
NSError
而不是
NSException
NSError
通常用于在预期可能出现错误的不同代码接口之间传递信息,其中as
NSException
更适用于意外错误,或由开发人员引起的错误,因此应在开发过程中处理

要从代码中的任何位置显示警报,您可以向应用程序委托添加一个方法,并使用
目标操作
传递错误。可能是这样的:

@protocol DLErrorPresentation <NSObject>
- (void)showAlertWithError:(NSError*)error sender:(id)sender
@end

- (void)showAlertWithError:(NSError*)error sender:(id)sender {
// Your alert presentation code
}

// In some view controller or view:
NSError* error;
if(![self somethingThatMayError:error]) {
  id<DLErrorPresentation> responder = [self targetForAction:@selector(showAlertWithError:sender:);
  [responder showAlertWithError:error sender:self]
}
@协议DlerorPresentation
-(无效)showAlertWithError:(n错误*)错误发送者:(id)发送者
@结束
-(无效)showAlertWithError:(n错误*)错误发送者:(id)发送者{
//您的警报演示文稿代码
}
//在某些视图控制器或视图中:
n错误*错误;
如果(![self somethingThatMayError:error]){
id响应程序=[self-targetForAction:@selector(showAlertWithError:sender:);
[响应者:错误发送者:自身]
}
为了提供额外的上下文,以下是苹果在其文档中对异常的描述:

对于编程错误或意外的运行时错误,如越界集合访问、尝试改变不可变对象、发送无效消息以及丢失与Windows服务器的连接,您应该保留使用异常的权利。通常,在创建应用程序时,您会处理这些类型的异常错误与运行时相比,r

建议使用错误对象(NSError)和Cocoa错误传递机制来传递Cocoa应用程序中的预期错误,而不是异常

尽管在许多编程环境中,异常通常用于控制编程流程或表示错误,但在Cocoa和Cocoa Touch应用程序中不要以这种方式使用异常。相反,您应该使用方法或函数的返回值来指示已发生错误,并以错误对象


您希望这样做是出于测试目的,还是为了在应用程序中实际发布?因为如果您正在测试,Xcode中有一种方法可以在异常抛出上设置断点(这可能是您想要的)。如果您希望在真实应用程序中发布此信息,我强烈建议您不要这样做-这将隐藏在崩溃报告中报告给您的真实错误和异常;通过捕获异常并向用户显示,您将完全丢失该信息。不,它将进入异常@catch block我以前做过此操作应用程序崩溃了,但进程本身没有崩溃,因为捕获到了异常。在捕获执行后,您可能会出现一个黑屏。@Umesh Verma的方法是处理此问题的传统方法。Crashlytics和其他大公司使用与Umesh相同的方法。我看不出您为什么要这样做,我建议您这样做因为@Dave Lyon指出的原因,我需要发布具有此功能的应用程序。不是为了调试
@protocol DLErrorPresentation <NSObject>
- (void)showAlertWithError:(NSError*)error sender:(id)sender
@end

- (void)showAlertWithError:(NSError*)error sender:(id)sender {
// Your alert presentation code
}

// In some view controller or view:
NSError* error;
if(![self somethingThatMayError:error]) {
  id<DLErrorPresentation> responder = [self targetForAction:@selector(showAlertWithError:sender:);
  [responder showAlertWithError:error sender:self]
}