【问题标题】:Practice for handling errors in Objective C client code处理 Objective C 客户端代码中的错误的实践
【发布时间】:2014-05-14 07:13:09
【问题描述】:

我已经看到了使用一系列实践的 Objective C 代码,从传递 NSError 指针以获取执行完成状态 - 到使用 NSAssert - 到实现 @throw - 到在回调中返回状态代码的委托上中继 -旧的 c 方法返回一个 boolean/int 表示 1 是成功和 co。

对于如何处理在客户端设备上运行的应用程序中发生的错误,我无法确定一致的模式。例如,对于以下情况,您建议如何处理:

  • 客户端尝试访问网络资源,网络资源超时/返回500?
  • 在逻辑代码部分甚至不应该发生的意外状态?
  • 尝试写入磁盘失败? (磁盘空间不足,不是权限和代码)

来自 Java,服务器端实践异常是首选武器,使用 Objective C 和 C 似乎存在异常但不鼓励。 NSAssert 似乎很苛刻,因为它会使应用程序崩溃,这在大多数情况下并不是最佳解决方案。所以,我很感激最佳实践建议。

【问题讨论】:

标签: objective-c exception-handling error-handling nsassert


【解决方案1】:

首先,我们必须就术语达成一致。我认为程序中有两种不好的情况:错误和异常。


错误 可能发生的意外情况,但您可以在程序内存处于一致状态的情况下从中恢复,并且可以继续进一步执行。

例如1。客户端尝试访问网络资源,网络资源超时/返回500? 例2。尝试写入磁盘失败? (磁盘空间不足,不是权限和代码)

方法以您希望的方式处理错误。显示用户消息,将其记录到文件/控制台,如果您认为需要报告,则将其报告给您的后端。


异常 一种本不应该达到的状态,并且可能会破坏应用程序的内存状态,从而阻止进一步执行。

这可能发生在两个层面。

第 1 级您忽略的逻辑错误,现在导致异常。

例如1。访问无效的数组元素,即索引超出范围异常。

在上面的例子中,你无意中犯了一个编程错误。你无法处理它,因为你忽略了它。这将使应用程序崩溃。

方法您的方法应该是识别错误并修复它。在这个过程中,一些最终用户会受到影响,最细致的软件就是这种情况。

2级

在编程时,您会遇到业务逻辑不允许的情况。

例如1。在逻辑代码部分达到了甚至不应该发生的意外状态?

例如2。根据您的业务逻辑,您始终希望出现的数据库条目。例如,假设您正在制作一个需要包含货币名称、货币的 unicode 符号和国家名称的货币表的应用程序。此表中的值将在您的 UI 中显示为下拉列表。您可以在首次启动应用程序时创建一个表并插入值,或者您可以在捆绑包中发送该表,但您始终希望它具有您要插入的值。您进行了一个 sqlite 选择查询->sqlite 执行成功->但没有返回任何值。业务逻辑要求值应该存在,但出于某种神秘的原因,它们不存在。

这是大多数混乱的根源,因为有时您可以通过将其中一些情况视为错误并向最终用户显示消息来从其中一些情况中恢复。这种方法错误。这是业务逻辑级别的异常。您应该防止发生的事情。

方法 您应该在开发和生产模式下使用 NSAssert 强制使应用程序崩溃。这是一种激进的方法,一些最终用户会受到影响,但我读过专家建议采取激进的方法来发现错误并修复它们,而不是假装它们不存在或认为你已经巧妙地覆盖了它们。完成是通过您的“处理策略”将异常掩盖为错误。我相信专家是对的。来自 Java,您可能会发现它是一种非常 objCeee.. 的处事方式。


Nils 和 Bools 您应该理解,它们只是在您将某事视为错误还是异常时得出的结论。它们本身并不是目的。在编写带有返回值的方法时,您应该定义 nil 或 bool(no) 的含义,并在方法之上记录您的意图。有时是错误,有时是异常,有时是正常的预期结果。在处理苹果框架/第三方库时,您应该了解它们返回此类值时的意图,并确定您希望如何在代码中处理它们。


其他一些提示

  1. 不要使用@try/catch,因为专家这么说。如果你想挑战他们,假设苹果把它放在那里是有原因的,苹果永远是对的,这些年来专家(包括苹果员工自己)都错了,你可以继续做。

  2. 正式确定您的方法->坚持下去->记录您的意图。不要一遍又一遍地思考。因为在某些阶段错误/异常/nils/bools 会跨越适当的界限并达到品味的范围。你最好一劳永逸地解决这个问题并腾出时间。

【讨论】:

  • paranoidcoder,这是一个有趣的实践。您能否参考上述意见?
  • @MaximVeksler 这是“The Mikeash”关于 NSAsserts 在生产代码中的使用的文章(阅读全文)。 Mikeash 是 Cocoa 社区中不需要介绍的人。 mikeash.com/pyblog/…。这个是关于不使用 BBum 的 NSExceptions 的,这是 Cocoa 社区的另一颗皇冠上的明珠。我想他已经为苹果工作了很长时间。 stackoverflow.com/questions/4310560/…。像我们这样的人应该在圣诞节给这些人送礼物。
【解决方案2】:

异常仅用于指示程序员错误和/或不可恢复的错误。异常不应用于流控制。 NSAssert 更像是一种开发工具。将 NSError 用于可恢复的、用户可寻址(或导致)的错误。

https://developer.apple.com/library/ios/documentation/Cocoa/Conceptual/ErrorHandlingCocoa/ErrorHandling/ErrorHandling.html

【讨论】:

  • bbum,我知道 NSError 是最佳选择,但我仍然想知道是否只在您想使应用程序崩溃时才使用异常,然后该语言是否实现了 @try & @catch范例?实现您不希望使用的东西的逻辑背后是什么?
猜你喜欢
  • 2021-02-11
  • 2020-10-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-05-25
  • 2018-03-21
相关资源
最近更新 更多