使用case switch代替多个if语句进行错误处理

3

我正在构建一个应用程序,该应用程序通过移动SAAS Parse进行登录。

登录请求可能会返回多个错误代码。目前针对每个错误代码运行if语句,并显示相关的警报视图,如下所示:

        if (error == nil) {
            // Something went wrong
            UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"LoginAlertErrorTitle", @"Login Error Alert View Title") message:NSLocalizedString(@"LoginStandardError", @"Login error message text - standard error") delegate:self cancelButtonTitle:nil otherButtonTitles:NSLocalizedString(@"GlobalOKButtonTitle", @"Global Ok button title"), nil];
            [alertView show];
        } else  if ([error code] == kPFErrorObjectNotFound) {
            UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"LoginAlertErrorTitle", @"Login Error Alert View Title") message:NSLocalizedString(@"LoginErrorObjectNotFound", @"Login error message text - object not found") delegate:self cancelButtonTitle:nil otherButtonTitles:NSLocalizedString(@"GlobalOKButtonTitle", @"Global Ok button title"), nil];
            [alertView show];
        } else  if ([error code] == kPFErrorConnectionFailed) {
            UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"LoginAlertErrorTitle", @"Login Error Alert View Title") message:NSLocalizedString(@"LoginAlertErrorConnection", @"Login error message text - connection failed") delegate:self cancelButtonTitle:nil otherButtonTitles:NSLocalizedString(@"GlobalOKButtonTitle", @"Global Ok button title"), nil];
            [alertView show];
        } else {
            NSLog(@"A Login error occurred: %i",[error code]);
            UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"LoginAlertErrorTitle", @"Login Error Alert View Title") message:[[error userInfo] objectForKey:@"error"] delegate:self cancelButtonTitle:nil otherButtonTitles:NSLocalizedString(@"GlobalOKButtonTitle", @"Global Ok button title"), nil];
            [alertView show];
        }

有没有更高效的方法来使用case/switching实现相同的功能?

实际的错误代码设置如下:

/*! @abstract 100: The connection to the Parse servers failed. */
extern NSInteger const kPFErrorConnectionFailed;

这让我想到可以在case语句中设置它。这是正确/最佳的方法吗?可能应该放在一个单独的方法中,例如handleErrorAlert:吗?

如何在上面的示例中编写此switch语句?

3个回答

10
无论你使用switch语句还是一系列的if-else if语句,实际上只是个人口味问题。是的,switch语句稍微更高效,但在这种情况下,实际上并不重要(不像你每秒钟要调用它数千次)。使用你认为更易读的方式。
尽管如此,你可能想稍微重构一下你的警告视图代码 - 在所有情况下你都在执行相同的操作,只有错误消息不同,因此存在大量重复代码。你可以像这样进行重构:
NSString *errorMessage = nil;
if (error == nil) {
    errorMessage = NSLocalizedString(@"LoginStandardError", @"Login error message text - standard error");
} else {
     switch ([error code]) {
          case kPFErrorObjectNotFound:
               errorMessage = NSLocalizedString(@"LoginErrorObjectNotFound", @"Login error message text - object not found");
               break;
          case kPFErrorConnectionFailed:
               errorMessage = NSLocalizedString(@"LoginAlertErrorConnection", @"Login error message text - connection failed");
               break;
          default:
               errorMessage = [[error userInfo] objectForKey:@"error"];
     }
}
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"LoginAlertErrorTitle", @"Login Error Alert View Title") 
                                                    message:errorMessage
                                                   delegate:self
                                          cancelButtonTitle:nil
                                          otherButtonTitles:NSLocalizedString(@"GlobalOKButtonTitle", @"Global Ok button title"), nil];
[alertView show];

太好了。从你的回答中,我完全明白了它是如何工作的,如何添加更多内容,正是我想要的。谢谢。 - StuartM

4

我认为在switch语句中使用typedef enum会是最清晰的方式。类似这样:

typedef enum
{
kServerError,
kInternetError,
kUnknowError
} kTypeError;

switch (aTypeError)
{
.
.
.
}

在您的情况下,您需要关注 switch 中的消息... UIAlertView 是一个常见的部分。因此:

NSString *aTitle = nil;
NSString *aMessage = nil;

switch (aTypeError)
{
    case kUnknowError:
    {
        aTitle = ...;
        aMessage = ...;
    }
    break;
}

UIAlertView *alertView = [UIAlertView alloc] ...

请问您能详细说明如何将我的现有代码整合到一个switch语句中吗? - StuartM
谢谢您的回复,但我不太理解这些设置。你有一个名为kTypeError的typedef枚举,然后是aTypeError的switch语句。那么在imp文件中,这个typedef的定义在哪里呢?参数如何被传递到switch语句本身中呢?也就是我接收到的返回错误代码?在UIAlertView信息方面,开关的区别在于什么,所以我认为它应该在switch语句本身内部。 - StuartM
aTypeError是类型为kTypeError的变量。typedef enum可以定义在pch文件中或者常量文件中。如何传递呢?这取决于您自己的架构(显然我不知道)。 - Rui Peres
你可以使用类似 kPFErrorWhatever 的 const 值来代替这个 typedef。但如果你想使用一个干净的枚举,你也可以给 typedef 分配值(我会编辑帖子以展示我的意思)。 - Marc

1
if (!error) {
    // Handle error (?).
}

switch ([error code]) {
    case kPFErrorObjectNotFound:
        // Handle error.
        break;
    case kPFErrorConnectionFailed:
        // Handle error.
        break;
    default:
        // Handle error.
}

只有当由-code返回的值可以在switch测试表达式中使用时,此方法才有效。据我所知,支持int——其他类型我不确定。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接