Ios 目标C-从块内部引发的捕获异常

Ios 目标C-从块内部引发的捕获异常,ios,objective-c,try-catch,objective-c-blocks,Ios,Objective C,Try Catch,Objective C Blocks,我正在应用程序中使用以下代码: @try { if(!self.usernameField.text || [self.usernameField.text isEqualToString:@""]) [NSException raise:@"Invalid value for username" format:@"Please enter your username."]; if(!self.passwordField.text ||

我正在应用程序中使用以下代码:

@try {
        if(!self.usernameField.text || [self.usernameField.text isEqualToString:@""])
            [NSException raise:@"Invalid value for username" format:@"Please enter your username."];

        if(!self.passwordField.text || [self.passwordField.text isEqualToString:@""])
            [NSException raise:@"Invalid value for password" format:@"Please enter your password."];


        [LoginManager
         userLogin:self.usernameField.text
         andPassword:self.passwordField.text
         success:^(AFHTTPRequestOperation *op, id response) {

             if([self.delegate respondsToSelector:@selector(loginSuccessWithUserName:)]) {
                 [self.delegate performSelector:@selector(loginSuccessWithUserName:)withObject:self.usernameField.text];
             }

             [self dismissPopoverController];
         }
         failure:^(AFHTTPRequestOperation *op, NSError *err) {
             NSString* nsLocalizedRecoverySuggestion = [err.userInfo objectForKey:@"NSLocalizedRecoverySuggestion"];

             if(err.code == -1009) {

                 [NSException raise:@"No Internet connection" format:@"It appears you’re not connected to the internet, please configure connectivity."];
             }

             if([nsLocalizedRecoverySuggestion rangeOfString:@"Wrong username or password."].location != NSNotFound) {

                 [NSException raise:@"Invalid username or password" format:@"Your given username or password is incorrect"];
             }
             else {
                 [NSException raise:@"BSXLoginViewController" format:@"Error during login"];
             }
         }];
    }
    @catch (NSException *exception) {
        UIAlertView* alert = [[UIAlertView alloc]initWithTitle:@"Login error"
                                                       message:exception.description
                                                      delegate:self
                                             cancelButtonTitle:@"Ok"
                                             otherButtonTitles:nil];
        [alert show];
    }
但是,在故障块中引发的异常不会在catch部分中被捕获。 我有点理解为什么它是合乎逻辑的,但我想知道是否有一种方法可以告诉块,内部发生的异常应该由我创建的catch部分处理

谢谢你的帮助

真诚地,
Zoli

不要被块与其他代码内联指定的事实所愚弄。您无法在外部(非块)代码中捕获块中的异常,因为TRY块中的代码已执行(并已退出),并且块仅在其自身范围内执行


解决方案是捕获块中的异常。

不要这样做。首先,我相信@bbum至少会对这一点发表评论,
NSException
在Objective-C中不适用于可恢复错误和通过代码传播可恢复错误(请参阅)。相反,Objective-C中使用的构造基本上是使用
NSException
处理不可恢复的编程错误,并使用
NSError
对象处理可恢复的错误

但是,这里有一个更大的问题,您正在进行的调用有块回调,因为它们在完成之前返回。在这种情况下,异常处理程序在实际抛出异常之前很久就退出了


在这种情况下,我建议通过调度到主队列并在那里显示
UIAlert
来删除异常并处理实际
failure:
块中的错误。

您需要将@try-@catch移动到faile块中。Сause fail block可能延迟调用/或者,不要在Objective-C内的控制流中使用Try/Catch。异常通常用于捕获程序员错误。在你的情况下,你可以处理块本身的异常情况,而不是把它扔到不同的上下文中。我只是不希望应用程序有几个退出点。所以我不想在代码中强制返回。我更喜欢每个函数应该只有一个返回点,如果相应地工作。如果不是,则将其作为异常处理(在本例中是一个N错误)。我不知道区别,但您是非常正确的!谢谢你指出这一点。这也成了我的解决办法。@gaige没有必要。你把它盖好了!还请注意,您应该使用
nsLocalizedRecoverysSuggestionErrorKey
而不是硬编码字符串