Objective-C 苹果开发文档 09 Dealing with Errors
2015-08-25 18:52
489 查看
DealingwithErrors
几乎所有的程序都会遇到错误。一些错误可能超出了你的控制范围,比如耗尽了内存空间或者失去了网络连接。一些错误是可以避免的,比如用户的无效输入。即使所有的开发人员都是精益求精的,程序设计员偶尔也会发生错误。如果你之前从事的是其他的平台和语言,你可能习惯使用异常来处理大多数的错误。当你用OC编写代码时,异常仅仅用于程序员错误,比如数组边界溢出的问题或者无效的方法参数。这些问题都是在你的程序上架之前可以发现并且改正的。
其他的错误都是用NSError类表示的。本章主要介绍如何使用NSError对象,包括如何处理框架方法失败和返回错误的问题。详见Error
HandlingProgrammingGuide。
UseNSErrorforMostErrors
在任何应用的生命周期内,错误都是不可避免的。例如,如果你需要从一个远程的web服务请求一个数据,会有各种各样的潜在问题出现,例如:Nonetworkconnectivity无网络连接
Theremotewebservicemaybeinaccessible远程网络服务不可到达
Theremotewebservicemaynotbeabletoservetheinformationyourequest远程web服务器没有你需要的信息
Thedatayoureceivemaynotmatchwhatyouwereexpecting你收到的数据和你需要的不匹配
遗憾的是,你不可能制定一个应急的计划,从而解决每一个可能发生的错误。相反,你只能为错误定制出一个计划,并且知道如何处理她们,从而给出最好的用户体验。
SomeDelegateMethodsAlertYoutoErrors
如果你使用一个框架类实现一个委托对象,从而执行一个特定的任务,比如从远程的web服务器下载信息,你会使用一个典型的错误处理方法。NSURLConnectionDelegate协议,包括一个connection:didFailWithError:方法:-(void)connection:(NSURLConnection*)connectiondidFailWithError:(NSError*)error; |
一个NSError对象包括一个数字错误代码,域名和描述,以及其他的相关信息,都被打包在一个用户信息字典里。
不是为每个可能的错误都分配一个特殊的数字代码,Cocoa和CocoaTouch中的错误被划分为许多区域。如果一个错误放生在NSURLConnection,上面的connection:didFailWithError:方法就会从NSURLErrorDomain提供一个错误。
错误对象也包含一个局部的描述,比如“Aserverwiththespecifiedhostnamecouldnotbefound.”(指定的主机名未被找到。)
SomeMethodsPassErrorsbyReference
一些Cocoa和CocoaTouch接口会通过引用来传回错误。例如,你可能需要把一个来自远程web服务器的数据写入到磁盘中,使用NSData方法writeToURL:options:error。方法中的最后一个参数就是一个NSError的指针。-(BOOL)writeToURL:(NSURL*)aURL |
options:(NSDataWritingOptions)mask |
error:(NSError**)errorPtr; |
NSError*anyError; |
BOOLsuccess=[receivedDatawriteToURL:someLocalFileURL |
options:0 |
error:&anyError]; |
if(!success){ |
NSLog(@"Writefailedwitherror:%@",anyError); |
//presenterrortouser |
} |
当通过引用来处理错误传递时,你需要测试一下方法的返回值,看看返回值是否会引发一个错误,就像上面显示的那样。不要只是测试错误指针是否被设置为指向一个错误。
Tip:如果你对错误对象不感兴趣,只需要给error:参数传递一个NULL。
RecoverifPossibleorDisplaytheErrortotheUser
最好的用户体验是将你的应用在一个错误中透明的恢复过来。例如,你发送了一个远程web服务器请求,如果未成功的话你可以试着再请求一次不同的服务器。这一次你可能需要对用户请求额外的数据,比如有效的用户名或者密码证书在尝试之前。如果不能从一个错误中恢复程序,你应该警告用户。如果你为iOS使用CocoaTouch,你需要创建安装一个UIAlertView用来显示错误。如果你为OSX使用Cocoa,你需要调用presentError:为任何NSResponder对象(比如一个视图,窗口或者程序对象自己本身),错误会向上传递相应器链条,为了更深层次的配置或者恢复。当她到达应用对象的时候,应用会通过一个警示面板显示错误给用户。
Formoreinformationonpresentingerrorstotheuser,seeDisplaying
InformationFromErrorObjects.
GeneratingYourOwnErrors
InordertocreateyourownNSErrorobjectsyou’llneedtodefineyourownerrordomain,whichshouldbeoftheform:
为了创建你自己的NSError对象,你需要定义你自己的错误域,形式如下:
com.companyName.appOrFrameworkName.ErrorDomain |
你需要为每个在你的错误域中可能发生的每个错误挑选一个特别的错误代码,同时需要一个合适的描述,描述存储在用户信息字典里,像这样:
NSString*domain=@"com.MyCompany.MyApplication.ErrorDomain"; |
NSString*desc=NSLocalizedString(@"Unableto…",@""); |
NSDictionary*userInfo=@{NSLocalizedDescriptionKey:desc}; |
NSError*error=[NSErrorerrorWithDomain:domain |
code:-101 |
userInfo:userInfo]; |
NSLocalizedStringfunctiontolookupalocalizedversionoftheerrordescriptionfroma
Localizable.stringsfile,
asdescribedinLocalizingStringResources.
Ifyouneedtopassbackanerrorbyreferenceasdescribedearlier,yourmethodsignatureshouldincludeaparameterforapointertoapointertoan
NSErrorobject.
Youshouldalsousethereturnvaluetoindicatesuccessorfailure,likethis:
-(BOOL)doSomethingThatMayGenerateAnError:(NSError**)errorPtr; |
NULLpointerwasprovidedfortheerrorparameterbeforeyou
attempttodereferenceittosettheerror,beforereturning
toNO
indicatefailure,likethis:
-(BOOL)doSomethingThatMayGenerateAnError:(NSError**)errorPtr{ |
... |
//erroroccurred |
if(errorPtr){ |
*errorPtr=[NSErrorerrorWithDomain:... |
code:... |
userInfo:...]; |
} |
returnNO; |
} |
ExceptionsAreUsedforProgrammerErrors
OC和其他的程序语言一样也支持异常用法,类似Java或者C++的语法。和NSError一样,异常在Cocoa和CocoaTouch中都是对象,通过NSException类实例表示。如果你需要写一个抛出异常的代码,你可以把代码封装到try-catch块中:
@try{ |
//dosomethingthatmightthrowanexception |
} |
@catch(NSException*exception){ |
//dealwiththeexception |
} |
@finally{ |
//optionalblockofclean-upcode |
//executedwhetherornotanexceptionoccurred |
} |
如果抛出一个异常没被捕获,那么默认的未捕获异常操作会输出一条消息在控制台上,同时终止程序运行。
你不应该使用try-catch块代替标准的OC方法检测。在NSArray的例子中,你应该总是检查一个数组中元素的个数,以便在使用下标访问之前确定好数组的下标。如果你的使用越界,objectAtIndex:方法会抛出异常,这样你就可以提前发现错误——在你将应用展示给用户的时候,你应该避免抛出异常。
FormoreinformationonexceptionsinObjective-Capplications,seeException
ProgrammingTopics.
相关文章推荐
- OutMan——Objective-C中的ARC介绍和block的使用
- Bug 9935857 - LOB indexes are missing from DBA_OBJECTS
- 关联(objc_setAssociatedObject、objc_getAssociatedObject、objc_removeAssociatedObjects)
- 论文提要“Fast Feature Pyramids for Object Detection”
- QObject是QT所有类的基类
- Objective-C实现信用卡校验
- Object-C 中各数据类型转换 NSData转NSString,Byte,UIImage
- 黑马程序员——ios基础---Objective-C:对象特性、面向对象
- cloudant DB save,Not a JSON Object
- object-c 与 js交互的学习
- sysbench: error while loading shared libraries: libmysqlclient.so.18: cannot open shared object file
- 多线程和MsgWaitForMultipleObjects
- OutMan——Objective-C内存管理
- Objective-C更改placeholder字体颜色
- Objective-C中的浅拷贝和深拷贝
- Objective-C 【@property和@synthesize关键字】
- Objective-C 【@property和@synthesize关键字】
- 用apktool反编译的时候出错:Exception in thread "main" brut.androlib.err.UndefinedResObject: resource spec:
- UVA - 1161 Objective: Berlin(最大流+时序模型)
- Object -C NSNumber -- 笔记