代码之家  ›  专栏  ›  技术社区  ›  John Gallagher

使用NSError更正结构以检查错误

  •  8
  • John Gallagher  · 技术社区  · 15 年前

    我正在编写各种例程,并尽我最大的努力使其保持整洁和重构。

    我创建的方法开始类似于以下代码:

    -(IBAction)buttonPress:(id)sender {
        // Create Document Shopping List with this document
        [self doSomething:&error];
    
        if(error) {
            [NSApp presentError:&error];
            return nil;
        }
    
        [self doSomethingElse:&error];
    
        if(error) {
            [NSApp presentError:&error];
            return nil;
        }
    
        [self doYetSomethingElse:&error];
    
        if(error) {
            [NSApp presentError:&error];
            return nil;
        }
    }
    

    我喜欢N错误,但这似乎是一种处理我所有错误的非常笨拙的方式。

    我对其他方法有一些想法:

    a) 错误检查可以内置到doSomething、doSomethingElse等方法中,但是如果不对返回值进行某种检查,我将无法退出按钮按下方法,这将导致我返回类似的结构。

    b) 我可以将NSError设置为关键值,但这方面的某些内容感觉非常错误。我非常清楚KVO可能会被滥用,所以我尝试在任何可能的情况下都不使用它。

    4 回复  |  直到 15 年前
        1
  •  12
  •   Kristian Glass adrianz    12 年前

    基本上,你不应该检查 NSError 对象以确定是否存在问题。您可以通过检查从方法返回的值来检查是否存在问题,该方法将指针指向 错误

    从…起 the Apple documentation :

    重要的 成功或失败由 方法虽然Cocoa方法在 方法通过直接返回来指示失败 nil NO ,你应该 始终检查返回值是否正确 对这件事做些什么 错误 对象

        2
  •  2
  •   danielpunkass    15 年前

    您问题的要点是,您是否可以对错误处理进行结构性改进。我这样认为,通过本质上引入更多的嵌套层,或者将更多代码提取到单独的方法/函数中,或者在高级示例方法中引入嵌套。

    使用“传播或处理”的思想,我将重写您的示例方法,如下所示:

    -(IBAction)buttonPress:(id)sender {
    
        // Create Document Shopping List with this document
        [self doSomething:&error];    
        if(error == nil) {
            [self doSomethingElse:&error];
            if (error == nil) {
                [self doYetSomethingElse:&error];
            }
        }
    
        if(error) {
            [NSApp presentError:&error];
        }    
    }
    

    请注意,对于在特定方法中引入太多嵌套,有一些很好的论据。像这样的嵌套本质上是提取方法的一种短期替代方法。例如,“doSomething:”本身称为doSomethingElse:,它称为doyetsomethingles:,这可能更有意义。这将在代码上施加与if嵌套相同的结构,但可以说更易于维护。

    另外,我不喜欢内联返回语句。在这个特定的实例中,sample方法实际上并不调用返回值,但是如果调用了,我更喜欢将局部变量设置为返回值,并且只在流控件的末尾返回。IMHO说,过早跳出函数或方法肯定会遇到奇怪的bug。

        3
  •  1
  •   Ben Gotow Dmitry Nogin    15 年前

        4
  •  0
  •   teabot    15 年前

    注: 当我发布这篇文章时,我并不知道有任何关于MacOS/Cocoa例外的争论。当你考虑这个答案时请记住这一点。

    为什么不使用 exceptions 相反这将允许您在方法上省去error参数,并在一个地方处理错误。

    -(IBAction)buttonPress:(id)sender {
        // Create Document Shopping List with this document
        @try {
            [self doSomething];
            [self doSomethingElse];
            [self doYetSomethingElse];
        } @catch (NSException* e) {
            [NSApp presentException:e];
        }
        return nil;
    }
    

    当然,您需要根据需要从doXXXX方法中抛出异常:

    NSException* e = [NSException exceptionWithName:@"MyException"
                                             reason:@"Something bad happened"
                                           userInfo:nil];
    @throw e;