我正在构建一个包含许多不同部分的应用程序,这些部分可以访问远程 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 }
所以,我有两个问题:
我有兴趣查看示例代码。错误处理可能是一个很大的痛苦,所以我想尽早解决这个问题。
备注:
您可以使用块做一些非常类似的事情:
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
块的效用是有限的。