0

我来自 Java 背景,其中 try/catch 是常见的做法。

在使用 Objective-c 几个月后,由于语言本身的性质以及不使用它的一般建议,我从未在我的 iOS 应用程序中实现 try/catch。

因此,我一直尝试构建无错误代码。但是,在撰写本文时,我仍然不知道如何在 Objective-c 中翻译这样一个简单的东西:

// some operation
try {
  // do some work
} catch (SomethingWentWrongException e) {
  // log error, inform user...etc
}
// some more operation and rest of the code

使用此代码操作,围绕 try/catch 执行,但程序没有中断,并且执行 catch 之后的其余代码。

然而,有一条规则告诉我们不应该使用 try catch 进行流量控制。我想用objective-c实现类似的东西,封装一些可能成功或失败的不太重要的操作,而不破坏工作流程。

如果没有objective-c @try,我怎么能做到这一点?

谢谢

4

2 回答 2

6

可以使用@try@catch(和@finally)在 Objective-C 中做到这一点。没有“规则”说你不这样做,但是在整个 Cocoa 和代码构建中都有一个普遍的设计习惯来与 Cocoa 集成:异常是为程序员错误保留的。这意味着如果使用你的 API 的人不遵守合同,或者不满足调用你的方法的一些先决条件,是许多 Objective-C 开发人员唯一会使用异常的时候。

在 Objective-C 代码中处理错误(例如我的文件消失了,我无法获得我需要的资源等)的常见习惯用法是使用 Cocoa 的 NSError 类,通过引用可能失败的方法传递一个实例。所以,重写你的例子:

// some operation
NSError *error;
BOOL itWorked = [object doSomeThingThatCouldFail: &error];
if (!itWorked) {
    // log error, inform user etc.
}
// some more operation and rest of the code

请注意,您检查方法的返回值以检查它是成功还是失败。该error对象保证设置为失败,但不承诺成功。

该方法的实现方式与错误一起工作:

- (BOOL)doSomeThingThatCouldFail: (NSError *__autoreleasing*)error {
  //...
  if (!success && error) //check that the user actually supplied an error pointer
  {
    NSDictionary *errorDetails = @{ ... };
    *error = [NSError errorWithDomain: @"Your error domain" code: someInteger userInfo: errorDetails];
  }
  return success;
}
于 2012-08-03T18:39:17.570 回答
0

有点离题,但我在几种情况下成功使用的习语可能需要在一系列子操作中间“中止”操作如下:

int rcode = 0;
do {
    rcode = operationA(xxx);
    if (rcode) break;
    rcode = operationB(xxx);
    if (rcode) break;
    ...
    rcode = operationZ(xxx);
    if (rcode) break;
} while (FALSE);

if (rcode) {
    <do recovery/error-reporting stuff>
}
else {
    <do stuff you'd do if successful>
}

一种穷人的尝试/捕捉——避免了如果你试图在每个单独的操作周围有一个完整的 if/then/else 的话你会遇到的意大利面条逻辑。(显然,您可以在每一步中选择性地设置一些状态变量,以了解您走了多远,错误原因是什么等)

于 2012-08-03T19:02:59.410 回答