创建一个标准的 try-catch-块以通过应用程序使用

问题描述 投票:0回答:2

我正在构建一个包含许多不同部分的应用程序,这些部分可以访问远程 API 调用(包括我自己的和其他人的)。可能会发生许多错误,并且为了加剧问题,不同的库以不同的方式处理这些错误。

本质上,我想对所有这些远程调用使用相同的错误处理块。

这就是我使用 Ruby 的方式,但我不太确定如何以同样的方式操作 Objective-C:

  //universal function to handle standard remote errors across errors
  def universal_handling
    begin
      yield
    rescue Exception => e
      // handle different exceptions accordingly  
      // allow crash if unexpected exception
    end
  end

  //how I would use the above block
  universal_handling{  //any of my remote call here  }

所以,我有两个问题:

  1. 如何在 Objective-C 中编写等效代码?至关重要的是我可以在整个应用程序中使用相同的处理块
  2. 在 iOS 开发中,这是好的做法吗?

我有兴趣查看示例代码。错误处理可能是一个很大的痛苦,所以我想尽早解决这个问题。

备注:

  1. 积木完全没问题。我无意支持< 4.2 versions.
  2. 我阅读了大部分文章,但没有回答如何使用块为特定的调用集编写“包装器”。
iphone objective-c ios ios4
2个回答
5
投票

您可以使用块做一些非常类似的事情:

typedef void(^WrappableBlock)(void);

^(WrappableBlock block) {
  @try {
    block();
  }
  @catch(...)
  }
    //handle exception
  }
}

但是,认识到 Cocoa(和 CocoaTouch)库“不是”异常安全是非常重要的。通过 Cocoa 框架抛出异常将导致各种问题,因为框架无法正确处理或清除异常,从而使您的应用程序处于可能不一致的状态。正确的 Cocoa 风格是使用 NSError 和返回标志来指示错误情况。这并不比使用异常更好或更坏,只是不同的哲学。


universal_handling

做类似于

NSError
的事情并不是那么简单,因为它要求你调用的任何东西都符合
NSError
模式。也就是说:

typedef BOOL(^WrappableBlock)(NSError**); ^(WrappableBlock block, NSError **err) { BOOL success = block(err); if(!success) { // handle error } return success; }

将包装任何采用 
just

NSError** 并返回

BOOL
来指示存在错误的方法。显然,这个包装器的实用性是有限的,因为您必须将任何有趣的方法包装在其他块中才能处理任何其他参数。当然,由于它是
NSError**
模式,因此您始终可以在您想要的时间/地点处理错误,并将
NULL
作为您不关心的
NSError**
参数传递(忽略返回值)。

最后一点:如果您使用的库可能引发异常,您

必须

在库调用的范围内捕获这些异常并处理它们。不要让异常传播,因为它们可能会通过 Cocoa 框架代码传播。因此,您提出的 universal_handling 块的效用是有限的。

    


0
投票
这篇不错的cocoawithlove文章

解释了如何处理Objective-C中未处理的异常以及如何从异常中恢复而不是“仅仅”崩溃。这可能是您正在寻找的一个很好的替代方案。 恐怕 Objective-C 不像 ruby 那样

动态

,这有点很难做到。 如果可能的话,也希望看到一个基于块的良好实现,即使我还没有使用它们,因为以前的版本兼容性。

© www.soinside.com 2019 - 2024. All rights reserved.