当前位置:  开发笔记 > 后端 > 正文

在objective-c/cocoa中抛出异常

如何解决《在objective-c/cocoa中抛出异常》经验,为你挑选了9个好方法。

在objective-c/cocoa中抛出异常的最佳方法是什么?



1> e.James..:

我使用[NSException raise:format:]如下:

[NSException raise:@"Invalid foo value" format:@"foo of %d is invalid", foo];


我一般也喜欢这个,但有一个问题.可能只是我当前的Xcode版本,但解析器似乎没有将[NSException raise ...]语法识别为返回值的方法的退出路径.在使用此语法时,我看到警告"控件可能达到非空函数的结束",但是使用@throw([NSException exceptionWith ...])语法,解析器将其识别为退出并且不显示警告.
我更喜欢这种方式与`@throw([NSException exceptionWith ...])`方法相比,因为它更简洁.
请务必阅读危害中的重要警告(http://stackoverflow.com/questions/324284/324805#324805)

2> harms..:

这里要谨慎.在Objective-C中,与许多类似的语言不同,您通常应该尽量避免对正常操作中可能发生的常见错误情况使用异常.

Apple的Obj-C 2.0文档声明如下:"重要:在Objective-C中,异常是资源密集型的.您不应该使用异常进行常规流量控制,或者只是表示错误(例如文件无法访问)"

Apple的概念异常处理文档解释相同,但更多的话:"重要:您应该保留使用异常编程或意外的运行时错误,例如越界集合访问,尝试改变不可变对象,发送无效消息并且失去了与窗口服务器的连接.在创建应用程序时而不是在运行时,通常会处理这些类型的错误和异常.[......]而不是异常,错误对象(NSError)和Cocoa错误传递机制是在Cocoa应用程序中传达预期错误的推荐方法."

其原因部分是为了坚持Objective-C中的编程习惯用法(在更复杂的情况下使用简单情况下的返回值和引用参数(通常是NSError类)),部分原因是抛出和捕获异常要贵得多,最后(并且最重要的是),Objective-C异常是C的setjmp()和longjmp()函数的一个薄包装,基本上搞乱了你仔细的内存处理,请参阅这个解释.


我认为这适用于大多数编程语言:"尽量避免在常见错误情况下使用异常".这同样适用于Java; 使用异常处理用户输入错误(例如)是不好的做法.不仅是因为资源使用,还因为代码清晰度.
"这同样适用于Java;" 不同意.您可以在Java中使用已检查的异常,以适应正常的错误条件.当然,您不会使用运行时异常.
更重要的是,Cocoa中的异常旨在表示不可恢复的程序错误.否则会针对框架运行,并可能导致未定义的行为.有关详细信息,请参见http://stackoverflow.com/questions/3378696/iphone-try-end-try/3379240#3379240.

3> Peter Hosey..:
@throw([NSException exceptionWith…])


@Steph Thirion:有关所有详细信息,请参阅http://developer.apple.com/documentation/Cocoa/Conceptual/Exceptions/Tasks/RaisingExceptions.html.底线?两者都可以,但@throw可用于抛出非NSException类的对象.
@StephThirion除了e.James的回复之外,重要的一点是Xcode将`@ throw`语句识别为函数退出点,如`return`语句.使用e.James的解决方案,您可能会错误地"控制可能会达到非空函数的结束"警告,而`@ throw`语法会避免这种警告.出于这个原因,我更喜欢e.James接受的解决方案.

4> Daniel Yanko..:

我没有代表对eJames的回应发表评论,所以我想我需要把它放在这里.对于那些来自Java背景的人,您会记得Java区分Exception和RuntimeException.异常是已检查的异常,并且未选中RuntimeException.特别是,Java建议使用"正常错误条件"的已检查异常和"由程序员错误导致的运行时错误"的未经检查的异常.似乎应该在使用未经检查的异常的相同位置使用Objective-C异常,并且在使用已检查异常的位置首选错误代码返回值或NSError值.



5> rustyshelf..:

我认为是一致的,使用@throw与你自己的类扩展NSException更好.然后你最后使用相同的符号来try catch:

@try {
.....
}
@catch{
...
}
@finally{
...
}

Apple在这里解释了如何抛出和处理异常: 捕获异常 抛出异常



6> Psycho..:

从ObjC 2.0开始,Objective-C异常不再是C的setjmp()longjmp()的包装器,并且与C++异常兼容,@ try是"免费的",但抛出和捕获异常的方式更加昂贵.

无论如何,断言(使用NSAssert和NSCAssert宏系列)抛出NSException,并且理所当然地将它们用作Ries状态.



7> Jason Fuerst..:

使用NSError来传达故障而不是异常.

关于NSError的快速点:

NSError允许C样式错误代码(整数)清楚地标识根本原因,并希望允许错误处理程序克服错误.您可以非常轻松地在NSError实例中包含SQL库(如SQLite)中的错误代码.

NSError还具有作为对象的优点,并提供了一种使用其userInfo字典成员更详细地描述错误的方法.

但最重要的是,不能抛出NSError,因此它鼓励采用更主动的错误处理方法,与其他语言相比,这些语言只是将热门土豆进一步向上调整堆栈,此时它只能报告给用户和没有以任何有意义的方式处理(如果你相信遵守OOP隐藏的最大信息原则).

参考链接: 参考



8> Johannes..:

这就是我从"The Big Nerd Ranch Guide(第4版)"中学到的:

@throw [NSException exceptionWithName:@"Something is not right exception"
                               reason:@"Can't perform this operation because of this or that"
                             userInfo:nil];



9> Subbu..:

您可以使用两种方法在try catch块中引发异常

@throw[NSException exceptionWithName];

或第二种方法

NSException e;
[e raise];

推荐阅读
ar_wen2402851455
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有