11 error-handling cocoa memory-management objective-c try-catch-finally
大家好.我一直在阅读Apple关于何时/何地/如何使用NSError与@ try/@ catch/@的建议.从本质上讲,我的印象是Apple认为最好避免使用异常处理语言结构,除非作为在意外错误情况下暂停程序执行的机制(也许有人可以举例说明这种情况?)
我来自Java,当有人想要处理错误时,会有例外.不可否认,我仍然在Java思想空间,但我正在慢慢掌握NSError所提供的所有内容.
我挂断的一件事是在发生错误时清理内存的任务.在许多情况下(例如使用C,C++库,CoreFoundation等),您需要在由于错误而导致函数中断之前进行大量内存清理.
这是我煮熟的一个例子,它准确地反映了我遇到过的情况.使用一些虚构的数据结构,该函数打开一个文件句柄并创建一个"MyFileRefInfo"对象,其中包含有关如何处理该文件的信息.在关闭文件句柄并释放struct的内存之前,对文件执行了一些操作.使用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;
}
Run Code Online (Sandbox Code Playgroud)
现在..我的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;
Run Code Online (Sandbox Code Playgroud)
我是不是觉得这是一个更优雅的解决方案,冗余代码更少?我错过了什么?
bbu*_*bum 17
丹尼尔的答案是正确的,但这个问题应该得到一个更直率的答案.
仅在遇到不可恢复的错误时抛出异常.
在传达可能从中恢复的错误情况时使用NSError.
在Apple框架中通过框架抛出的任何异常都可能导致未定义的行为.
开发中心提供了一个Exceptions编程主题文档.
Dan*_*sky 12
从本质上讲,我的印象是Apple认为最好避免使用异常处理语言结构,除非作为在意外错误情况下暂停程序执行的机制(也许有人可以举例说明这种情况?)
这不是我的印象.我认为Apple建议使用异常来实现真正的异常条件,并将NSError用于预期的失败.既然你来自Java,我认为NSError - > java.lang.Exception和Obj-C Exceptions - > java.lang.RuntimeException.当程序员做错了(例如,错误地使用API)时使用Obj-C异常,并在发生预期故障时使用NSError(例如,找不到远程服务器).
当然,这只是我对Apple的立场的解释.另一方面,我喜欢异常!
小智 3
Objective-C 中的异常在历史上一直是“严重的”,进入 try 块会带来性能成本、抛出成本、使用finally 的成本等等。因此,Cocoa 开发人员通常会避免“哦不,”之外的异常。 “天塌下来了”的各种情况——如果文件丢失,则使用 NSError,但如果没有文件系统且可用内存量为负,则例外。
这就是历史的观点。但是,如果您在 10.5 或更高版本上构建 64 位应用程序,则异常架构已被重写为“零成本”,这可能意味着历史视图不再相关。与任何事情一样,这取决于多种因素 - 一种工作方式是否对您来说更自然并且可以让您更快地完成,如果您没有遇到任何与性能相关的问题,以及如果稍微与“传统”Objective-C 代码不一致不会打扰您...那么就没有理由不使用异常。
| 归档时间: |
|
| 查看次数: |
7790 次 |
| 最近记录: |