大家好。我一直在阅读 Apple 关于何时/何地/如何使用 NSError 与 @try/@catch/@finally 的建议。从本质上讲,我的印象是 Apple 认为最好避免使用异常处理语言结构,除非作为在意外错误情况下停止程序执行的机制(也许有人可以举一个这种情况的例子?)
我来自 Java,当一个人想要处理错误时,异常是要走的路。诚然,我仍然在 Java 思想领域,但我正在慢慢掌握 NSError 所提供的一切。
我挂断的一件事是发生错误时清理内存的任务。在许多情况下(例如,使用 C、C++ 库、CoreFoundation 等),您需要在因错误而中断函数之前进行大量内存清理。
这是我编写的一个示例,它准确地反映了我遇到的情况。使用一些虚构的数据结构,该函数打开一个文件句柄并创建一个“MyFileRefInfo”对象,其中包含有关如何处理文件的信息。在关闭文件句柄并释放结构的内存之前,对文件进行了一些处理。使用Apple的建议我有这个方法:
- (BOOL)doSomeThingsWithFile:(NSURL *)filePath error:(NSError **)error
{
MyFileReference inFile; // Lets say this is a CF struct that opens a file reference
MyFileRefInfo *fileInfo = new MyFileRefInfo(...some init parameters...);
OSStatus err = OpenFileReference((CFURLRef)filePath ,&inFile);
if(err != NoErr)
{
*error = [NSError errorWithDomain:@"myDomain" code:99 userInfo:nil];
delete fileInfo;
return NO;
}
err = DoSomeStuffWithTheFileAndInfo(inFile,fileInfo);
if(err != NoErr)
{
*error = [NSError errorWithDomain:@"myDomain" code:100 userInfo:nil];
CloseFileHandle(inFile); // if we don't do this bad things happen
delete fileInfo;
return NO;
}
err = DoSomeOtherStuffWithTheFile(inFile,fileInfo);
if(err != NoErr)
{
*error = [NSError errorWithDomain:@"myDomain" code:101 userInfo:nil];
CloseFileHandle(inFile); // if we don't do this bad things happen
delete fileInfo;
return NO;
}
CloseFileHandle(inFile);
delete fileInfo;
return YES;
}
现在.. 我的 Java 逻辑告诉我,最好将其设置为 try/catch/finally 结构并将所有调用以关闭文件句柄并在 finally 块中释放内存。
像这样。。
...
@try
{
OSStatus err = OpenFileReference((CFURLRef)filePath ,&inFile);
if(err != NoErr)
{
... throw some exception complete with error code and description ...
}
err = DoSomeStuffWithTheFileAndInfo(inFile,fileInfo);
if(err != NoErr)
{
... throw some exception ...
}
... etc ...
}
@catch(MyException *ex)
{
*error = [NSError errorWithDomain:@"myDomain" code:[ex errorCode] userInfo:nil];
return NO;
}
@finally
{
CloseFileHandle(inFile); // if we don't do this bad things happen
delete fileInfo;
}
return YES;
我是否疯狂地认为这是一个更优雅的解决方案,冗余代码更少?我错过了什么?