我已经看到使用一系列实践的Objective C代码,从将NSError的指针传递给执行完成状态 - 到使用NSAssert - 来实现@throw - 在委托中转换回调中返回的状态代码 - 返回boolean / int的旧c方法,表示1为成功和co。
我无法确定一致的模式,我应该如何处理在客户端设备上运行的应用中发生的错误。例如,您建议处理以下情况:
来自Java,服务器端实践异常选择的武器,使用Objective C和C似乎存在异常但不鼓励。 NSAssert似乎很苛刻,因为它会使应用程序崩溃,在大多数情况下这不是最佳解决方案。所以,我很欣赏最佳实践建议。
答案 0 :(得分:2)
异常仅用于指示程序员错误和/或不可恢复的错误。不应将异常用于流量控制。 NSAssert更像是一种开发工具。将NSError用于可恢复的,用户可寻址的(或导致的)错误。
答案 1 :(得分:0)
首先,我们必须就术语达成一致。我认为程序中存在两种类型的错误情况:错误和异常。
错误可能发生的不需要的情况,但您可以在程序内存处于一致状态的情况下从中恢复,并且可以继续执行。
EG1。客户端尝试访问网络资源,网络资源超时/返回500? EG2。尝试写入磁盘失败? (磁盘空间不足,不是权限和代码)
方法以您希望的方式处理错误。显示用户消息,将其记录到文件/控制台,如果您认为需要报告,则将其报告给后端。
异常应该永远不会达到的状态,并且可能以阻止进一步执行的方式破坏应用程序的内存状态。
这可能发生在两个层面。
等级1 您忽略了一个逻辑错误,现在导致异常。
EG1。访问无效的数组元素,即索引超出范围的异常。
在上面的例子中,你无意识地犯了编程错误。你无法处理它,因为你忽略了它。这会使应用程序崩溃。
方法您的方法应该是识别错误并修复它。在这个过程中,一些最终用户将受到影响,这是最细致的软件的情况。
等级2
在编程时,您会遇到业务逻辑不允许的情况。
EG1。在逻辑代码部分中达到了应该没有发生的意外状态?
EG2。根据您的业务逻辑,您始终希望存在的数据库条目。例如,假设您正在创建一个应用程序,该应用程序需要带有货币名称的货币表,货币和国家/地区名称的unicode符号。此表中的值将在UI中显示为下拉列表。您可以在首次启动应用程序时创建一个表并插入值,也可以在捆绑包中运送该表,但您始终希望它具有您要插入的值。您进行sqlite select query-> sqlite execution succeeded->但不返回任何值。业务逻辑要求存在价值,但出于某种神秘的原因,它们不存在。
这是大多数混淆源于此的地方,因为有时您可以通过将其视为错误并向最终用户显示消息来从某些情况中恢复。这种方法错误。这是业务逻辑级别的一个例外。一个你应该防止发生的事情。
方法您应该在开发和生产模式下使用NSAssert强制崩溃应用程序。这是一种积极的方法,一些最终用户会受到影响,但我已经阅读过专家建议采用积极的方法来发现错误并对其进行补救而不是假装它们不存在或认为你已经巧妙地覆盖它们所有你拥有的完成是通过“处理策略”将异常掩盖为错误。我相信专家是对的。来自Java,您可能会发现它是一种非常客观的做事方式。
Nils and Bools 您应该明白,他们只是在您将某事视为错误或例外的结论时达成的促进者。它们本身并不是目的。在使用返回值编写方法时,您应该定义nil或bool(no)表示什么,并在方法之上记录您的意图。有时它会是一个错误,有时它会是一个例外,有时它可能是一个正常的预期结果。在处理Apple框架/第三方库时,您应该了解他们返回此类值时的意图,并确定您希望如何在代码中处理它们。
其他一些提示
不要使用@ try / catch,因为专家这样说。如果你想挑战他们,假设苹果公司出于某种原因把它放在那里,苹果公司总是对的,专家(包括苹果公司员工自己)在这些年后都弄错了,你可以继续做下去。
将您的方法正式化 - >坚持下去 - >记录您的意图。不要一遍又一遍地思考它。因为在某些阶段,错误/异常/ nils / bools将超越适当的限制并达到品味区域。你最好一劳永逸地解决这个问题并节省你的时间。