【问题标题】:Handling errors and exceptions on the iPhone处理 iPhone 上的错误和异常
【发布时间】:2010-11-16 12:49:40
【问题描述】:

我正在为 iPhone 开发一个 Core Data 应用程序,我是整个平台等方面的新手。

我的问题是,我应该查找和处理多少错误和异常,例如在打开持久存储时。例如,查看“位置”核心数据教程(希望可以像这样在这里引用它):

(在代码中查看我的一些问题)

- (void)applicationDidFinishLaunching:(UIApplication *)application {
   ...    
   NSManagedObjectContext *context = [self managedObjectContext];
   if (!context) {
       // Handle the error. Can this ever happen with this code? (see next comment below)



- (NSManagedObjectContext *) managedObjectContext {
   ...
   NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];
   // it seems even if I get an error or exception down in persistentStoreCoordinator,
   // coordinator will still never be nil, or?  
   if (coordinator != nil) {
        managedObjectContext = [[NSManagedObjectContext alloc] init];
        [managedObjectContext setPersistentStoreCoordinator: coordinator];
   }
   return managedObjectContext;   
}



- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {
   ...
   NSError *error;
   // should i have an:  if managedObjectModel != nil   here?
   persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] [initWithManagedObjectModel: [self managedObjectModel]];
   //need a @try here too?
   if (![persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeUrl options:nil error:&error]) {
       // Handle error, do what?   
   }    
   return persistentStoreCoordinator;    
}


- (NSManagedObjectModel *)managedObjectModel {
   ...
   //should have a @try here? But how to handle caught exceptions? Just return nil?
   managedObjectModel = [[NSManagedObjectModel mergedModelFromBundles:nil] retain];    
   return managedObjectModel;
}

所以问题真的是在哪里寻找错误,在哪里寻找异常,如何以及何时向上传播,以及如何在 iPhone 上以好的方式处理严重错误?


编辑:在收到对此问题和我的其他相关问题的一些答案后,我对我试图提出的问题有了一些澄清:

我现在明白 cocoa 中的异常主要用于查找程序员错误,而不是运行时错误。您是否会在发布应用程序时不包括任何异常处理(如果出于调试原因未添加)?还是我仍然应该进行防御性编程并使用大量@try?

由于 iPhone 应用程序是沙盒化的,并且用户无法访问文件系统,因此在设计基于 sqlite 的核心数据应用程序时应该寻找哪些可能的运行时错误?我的意思是,数据库文件不太可能消失......但也许未来的升级可能会失败,留下一个旧的无效 sqlite 数据库......有什么好的做法?

另外,像 object alloc 这样的其他东西可能极不可能失败?在那之前很久你就会收到内存不足的警告......或者......?

而且,考虑到上述示例中的错误和异常处理,什么是好的编程实践,我可以在方法中“深入”地得到一个错误......我应该在那里处理错误还是等到它到达顶部以某种形式(例如 nil 对象),还是以连锁反应的方式处理它们?

以及,如何处理它们?登录到 NSLog 并继续?显示一个模态信息框并锁定等待用户退出应用程序?还是“错误 xxx,按 OK 退出应用”?

还有,有没有办法直接显示模态对话框?我注意到我引发的一些会显示对话框的错误从未显示出来,因为应用程序继续运行并随后崩溃....有 SHOW NOW 方法吗?

很多问题,希望您至少有兴趣回答其中的一些问题,并且这可能会引起其他人的兴趣!

Rgds 下午

【问题讨论】:

  • Petter,或者和编辑,你能修正你的格式吗?几乎不可能发现你的内联 cmets 指的是什么。

标签: iphone objective-c core-data exception-handling error-handling


【解决方案1】:

如果文档要求,您应该检查错误。

例如,在NSPersistentStoreCoordinator:addPersistentStoreWithType:configuration:URL:options:error: 文档的文档中,请注意它说:

返回值

新创建的商店,如果发生错误,则为 nil。

这意味着在发生错误的情况下返回 nil。您应该检查它,否则您将获得对 nil 的引用,一旦您尝试使用它,导致运行时异常。对于应用程序来说,这不是一种优雅的运行方式 - 意外崩溃对于任何类型的用户应用程序来说都是不可接受的行为。

在 Objective-C 中,您通常应该不必处理异常,因为它们用于异常情况。出于各种非常好的原因,其他一些语言使用异常作为指示正常错误条件的更好方法。然而,这不是 Objective-C 中的约定。

所以你的问题的答案是:当 API 告诉你函数可以在错误情况下返回 nil 时,你应该始终处理错误。

如果文档告诉您预期并处理异常,那么就这样做。否则不要。唯一的例外是iff 您知道自己在做什么以及为什么。

【讨论】:

  • 谢谢,将检查所有重要电话的文档!如上所述,在我编辑的问题中,我仍然可以在编程实践中使用一些进一步的帮助......
【解决方案2】:

正如我在对您的其他问题的评论中所说,异常仅由 Cocoa API 用于指示程序员似乎出错的事情 - 数组超出范围,Core Data 数据库的架构错误等等。错误用于指示用户可能导致发生的事情 - 文件不存在,网络操作未完成等。因此作为粗略的经验法则,在开发过程中寻找异常并作为程序员粉碎它们- 引入错误。准备好处理生产中的错误并从中恢复。

Mac 上的一个重要边缘案例是分布式对象,它使用异常来处理连接的另一端断开或安全验证不成功等情况。

【讨论】:

  • 感谢您对此做出更好的解释!我现在编辑了这篇文章,以进一步解释我还想了解的其他内容。
猜你喜欢
  • 2014-04-06
  • 2012-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-09-16
  • 1970-01-01
  • 1970-01-01
  • 2016-05-17
相关资源
最近更新 更多