0

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

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

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

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

4

2 回答 2

2

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

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

于 2014-04-02T23:27:08.613 回答
0

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


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

例如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 会跨越适当的界限并达到品味的范围。你最好一劳永逸地解决这个问题并腾出时间。

于 2014-04-07T05:35:53.670 回答