1

提前,请原谅我对iPhone/Objective-C最佳实践缺乏理解;我来自.NET/C#背景。iPhone生产/发布异常处理

尽管我已经阅读了许多关于iPhone异常处理的文章,但我仍然不完全清楚大多数人为生产代码所做的工作。此外,我还没有找到任何开放源码的应用程序,我通常会期望错误处理。这里是我的问题:

1)如果意外的结果发生会导致应用程序最终失败,你会抛出一个异常或只是等待它失败以后?例如,

if (![fileManager createDirectoryAtPath: myNewDir 
    withIntermediateDirectories: YES 
    attributes: nil 
    error: &myError]) { 

    // My app shouldn't continue. Should I raise an exception? 
    // Or should I just log it and then wait for it to crash later? 
} 

2)您是否验证参数?例如,在C#中,我通常会检查null,如果需要的话抛出一个ArgumentNullException。

3)当应用程序崩溃时,崩溃信息会自动记录,还是需要设置未处理的异常处理程序?我可以在此方法中显示UIAlertView以通知用户发生了什么不愉快的事情,而不是让应用程序消失吗? (如果是这样,我不能得到它的工作。)

4)最后,为什么我没有看到任何人最终使用@ try/@ catch/@?它在C#中广泛使用,但我还没有找到使用它的开源应用程序。 (也许我只是看着错误的应用程序。)

回答

2

Ad 1.您给出的例子是一个有点经典的例子,当时应该在Java中使用“checked异常”。该方法的调用者必须准备好,该调用可能因为可以控制的原因而失败。特别是,在给出的示例中,我将允许错误描述对象允许传播给调用者:

- (BOOL) prepareDirectories: (NSString*) path error: (NSError**) location { 

    if(![fileManager createDirectoryAtPath: path 
         withIntermediateDirectories: YES 
         attributes: nil 
         error: location]) { 

     return NO; 
    } 

    // ... additional set-up here 
    return YES; 
} 

如果错误真的是不可恢复的,你实际上可能引发异常,但也将被没收任何机会向您的应用程序的用户显示适当的错误消息。

广告2.是的,参数确认绝对是您应该做的。并提出意想不到的nil的例外是完全合适的。一个错误的参数是“程序员的错误”,你不能保证程序仍然处于一致的状态。例如,如果尝试使用不存在的索引获取元素,NSArray会引发异常。

广告3.当应用程序由于未捕获的异常而崩溃时,事实会自动记录。如果您确实想要显示错误消息,则可以捕获该异常。但是,该应用可能处于不一致的状态,并且不应该被允许继续,所以简单地允许它停下来似乎是最好的解决方案。

广告4.我不知道。

1
  1. 在您提到的具体情况下,您应该向用户提供有关如何解决情况的说明刚刚发生的通知。除非在极端情况下你的应用程序不应该退出。你应该让用户解决任何错误,然后再试一次。
  2. 参数验证取决于很多因素。有一点需要记住的是,在Obj-C中,发送消息到nil是完全有效的(如果你这样做,没有任何反应),所以在很多情况下你不需要检查零。如果我在模型类中,我总是在方法中验证参数。如果我不是,我几乎从不验证任何东西,类型检查就足够了。
  3. 应记录一些信息,但记录更多具体信息对您的情况总是有帮助的。理想情况下,您不应该达到未处理的异常状态。
  4. 可可类很少会因为环境原因抛出异常,它们几乎总是因为你做错了什么。例如,你通常不会在[NSString stringWithString:]周围放置一个@ try/@ catch块,因为它会抛出异常的唯一方式是如果你尝试并通过nil。确保你没有通过nil,你不必担心捕捉异常。当一个方法可能因为你不能控制的东西而失败时,它们通常通过NSError进行通信。例如,请参阅- (BOOL)save:(NSError **)error方法NSManagedObjectContext