处理iPhone上的错误和异常

时间:2009-08-03 22:44:17

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

我正在为iPhone开发核心数据应用程序,我是整个平台等的新手。

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

(我在一些遗言的代码中评论)

- (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数据库....什么是好的做法?

此外,像对象分配这样的其他东西很可能不会失败?在这种情况发生之前很久你会得到一个低内存警告......或者......?

并且,在上面的例子中考虑错误和异常处理的好编程实践是什么,我可以在方法中“深入”地得到错误...我应该在那里处理错误还是等到它到达顶部以某种形式(例如零物体),或者在连锁反应中处理它们?

而且,如何处理它们?登录NSLog继续?显示模态信息框并锁定等待用户退出应用程序?或者“错误xxx,按确定以退出应用程序”?

而且,有没有办法直接显示模态对话框?我注意到我挑起的一些错误会显示一个对话框从未显示出因为应用程序继续而后来崩溃....是否有一个SHOW NOW方法?

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

RGDS PM

3 个答案:

答案 0 :(得分:2)

正如我在对你的另一个问题的评论中所说,Cocoa API仅使用异常来表明程序员出错的情况 - 数组超出范围,Core Data数据库的模式错误错误用于表示用户可能导致发生的事情 - 文件不存在,网络操作未完成等。因此,作为一个粗略的经验法则,在开发过程中查找异常并将其粉碎为程序员 - 介绍的错误。准备好处理并从生产中的错误中恢复。

Mac上的一个重要边缘案例是分布式对象,它使用异常来处理连接的另一端消失或安全验证没有成功。

答案 1 :(得分:1)

如果文档说明,您应该检查错误。

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

  

返回值

     

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

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

在Objective-C中,您通常必须处理异常,因为它们用于异常情况。由于各种原因,一些其他语言使用异常作为指示正常错误条件的更好方法。但是,这不是Objective-C中的惯例。

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

如果文档告诉您期望和处理异常,那么请执行此操作。否则不要。唯一的例外是 iff 您知道自己在做什么以及为什么。

答案 2 :(得分:0)