简体   繁体   English

Objective C - 从块内部引发的Catch异常

[英]Objective C - Catch exception raised from inside a block

I'm using the following code in app: 我在app中使用以下代码:

@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];
    }

However the exceptions raised in the failure block don't get catched in the catch section. 但是,在故障块中引发的异常不会在catch部分中被捕获。 I kind of understand why it's logical, but i would like to know if there's a way to tell the block that the exceptions happening inside should be handled by the catch section i created. 我有点理解为什么它是合乎逻辑的,但是我想知道是否有办法告诉块我内部发生的异常应该由我创建的catch部分来处理。

Thanks for any help! 谢谢你的帮助!

Sincerely, Zoli 真诚的,佐利

Don't do this. 不要这样做。 First of all, and I'm sure you'll get at least a comment from @bbum about this, NSException isn't intended in Objective-C for recoverable errors and propagating recoverable errors through code (see Introduction to Exception Programming Topics for Cocoa ). 首先,我确信你至少会得到@bbum关于这个的评论, NSException不是用于Objective-C中的可恢复错误和通过代码传播可恢复的错误(参见Cocoa的异常编程主题简介) )。 Instead, the construct used in Objective-C is to use NSException basically for unrecoverable programming errors, and to use NSError objects for handing around recoverable errors. 相反,Objective-C中使用的NSException基本上是针对不可恢复的编程错误使用NSException ,并使用NSError对象来处理可恢复的错误。

However, you've got a bigger problem here in that the calls that you are making have block callbacks because they return before completing. 但是,你在这里遇到了一个更大的问题,你正在进行的调用会阻止回调,因为它们会在完成之前返回。 In this case, your exception handler is exited long before the exceptions are actually thrown. 在这种情况下,在实际抛出异常之前很久就会退出异常处理程序。

In this case, I'd suggest removing the exceptions and handling the errors inside of the actual failure: block by dispatching to the main queue and presenting the UIAlert there. 在这种情况下,我建议删除异常并处理实际failure:的错误failure:通过调度到主队列并在那里呈现UIAlert

Don't be fooled by the fact that your block is specified inline with other code. 不要被你的块与其他代码内联指定这一事实所迷惑。 You cannot catch exceptions in the block in the outer (non-block) code because the code in the TRY block has already executed (and exited) and the block only executes in it's own scope. 您无法在外部(非块)代码中捕获块中的异常,因为TRY块中的代码已经执行(并退出),并且块仅在其自己的范围内执行。

A solution is to catch exceptions in the block. 解决方案是捕获块中的异常。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM