objective-c 在objective-c/cocoa 中抛出异常

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/324284/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 20:56:57  来源:igfitidea点击:

throwing an exception in objective-c/cocoa

objective-ccocoaexception-handling

提问by Steph Thirion

What's the best way to throw an exception in objective-c/cocoa?

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

回答by e.James

I use [NSException raise:format:]as follows:

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

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

回答by harms

A word of caution here. In Objective-C, unlike many similar languages, you generally should try to avoid using exceptions for common error situations that may occur in normal operation.

这里要注意一点。在 Objective-C 中,与许多类似的语言不同,对于正常操作中可能出现的常见错误情况,您通常应该尽量避免使用异常。

Apple's documentation for Obj-C 2.0states the following: "Important: Exceptions are resource-intensive in Objective-C. You should not use exceptions for general flow-control, or simply to signify errors (such as a file not being accessible)"

Apple 的 Obj-C 2.0 文档声明如下:“重要:异常在 Objective-C 中是资源密集型的。您不应将异常用于一般流控制,或仅用于表示错误(例如文件不可访问)”

Apple's conceptual Exception handling documentationexplains the same, but with more words: "Important: You should reserve the use of exceptions for programming or unexpected runtime errors such as out-of-bounds collection access, attempts to mutate immutable objects, sending an invalid message, and losing the connection to the window server. You usually take care of these sorts of errors with exceptions when an application is being created rather than at runtime. [.....] Instead of exceptions, error objects (NSError) and the Cocoa error-delivery mechanism are the recommended way to communicate expected errors in Cocoa applications."

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

The reasons for this is partly to adhere to programming idioms in Objective-C (using return values in simple cases and by-reference parameters (often the NSError class) in more complex cases), partly that throwing and catching exceptions is much more expensive and finally (and perpaps most importantly) that Objective-C exceptions are a thin wrapper around C's setjmp() and longjmp() functions, essentially messing up your careful memory handling, see this explanation.

部分原因是为了遵守 Objective-C 中的编程习惯(在简单情况下使用返回值,在更复杂情况下使用 by-reference 参数(通常是 NSError 类)),部分原因是抛出和捕获异常的成本要高得多并且最后(最重要的是)Objective-C 异常是 C 的 setjmp() 和 longjmp() 函数的一个薄包装,基本上搞砸了您仔细的内存处理,请参阅此解释

回答by Peter Hosey

@throw([NSException exceptionWith…])

Xcode recognizes @throwstatements as function exit points, like returnstatements. Using the @throwsyntax avoids erroneous "Control may reach end of non-void function" warnings that you may get from [NSException raise:…].

Xcode 将@throw语句识别为函数出口点,就像return语句一样。使用@throw语法错误避免“控制可以达到非void函数结束”的警告,你可以得到[NSException raise:…]

Also, @throwcan be used to throw objects that are not of class NSException.

此外,@throw可用于抛出不属于 NSException 类的对象。

回答by Daniel Yankowsky

Regarding [NSException raise:format:]. For those coming from a Java background, you will recall that Java distinguishes between Exception and RuntimeException. Exception is a checked exception, and RuntimeException is unchecked. In particular, Java suggests using checked exceptions for "normal error conditions" and unchecked exceptions for "runtime errors caused by a programmer error." It seems that Objective-C exceptions should be used in the same places you would use an unchecked exception, and error code return values or NSError values are preferred in places where you would use a checked exception.

关于[NSException raise:format:]. 对于那些有 Java 背景的人,您会记得 Java 区分 Exception 和 RuntimeException。Exception 是已检查的异常,而 RuntimeException 是未检查的。特别是,Java 建议对“正常错误条件”使用已检查的异常,对“由程序员错误引起的运行时错误”使用未检查的异常。似乎应该在使用未检查异常的相同位置使用 Objective-C 异常,并且在使用已检查异常的地方首选错误代码返回值或 NSError 值。

回答by rustyshelf

I think to be consistant it's nicer to use @throw with your own class that extends NSException. Then you use the same notations for try catch finally:

我认为要保持一致,最好将 @throw 与您自己的扩展 NSException 的类一起使用。然后你对 try catch 最后使用相同的符号:

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

Apple explains here how to throw and handle exceptions: Catching ExceptionsThrowing Exceptions

Apple 在这里解释了如何抛出和处理异常: Catching Exceptions Throwing Exceptions

回答by Psycho

Since ObjC 2.0, Objective-C exceptions are no longer a wrapper for C's setjmp() longjmp(), and are compatible with C++ exception, the @try is "free of charge", but throwing and catching exceptions is way more expensive.

从 ObjC 2.0 开始,Objective-C 异常不再是 C 的 setjmp() longjmp() 的包装器,并且与 C++ 异常兼容,@try 是“免费的”,但抛出和捕获异常的成本更高。

Anyway, assertions (using NSAssert and NSCAssert macro family) throw NSException, and that sane to use them as Ries states.

无论如何,断言(使用 NSAssert 和 NSCAssert 宏系列)会抛出 NSException,并且将它们用作 Ries 状态是明智的。

回答by Jason Fuerstenberg

Use NSError to communicate failures rather than exceptions.

使用 NSError 来传达失败而不是异常。

Quick points about NSError:

关于 NSError 的要点:

  • NSError allows for C style error codes (integers) to clearly identify the root cause and hopefully allow the error handler to overcome the error. You can wrap error codes from C libraries like SQLite in NSError instances very easily.

  • NSError also has the benefit of being an object and offers a way to describe the error in more detail with its userInfo dictionary member.

  • But best of all, NSError CANNOT be thrown so it encourages a more proactive approach to error handling, in contrast to other languages which simply throw the hot potato further and further up the call stack at which point it can only be reported to the user and not handled in any meaningful way (not if you believe in following OOP's biggest tenet of information hiding that is).

  • NSError 允许 C 风格的错误代码(整数)清楚地识别根本原因,并希望允许错误处理程序克服错误。您可以非常轻松地将来自 C 库(如 SQLite)的错误代码包装在 NSError 实例中。

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

  • 但最重要的是,NSError 不能被抛出,因此它鼓励了一种更主动的错误处理方法,与其他语言相比,这些语言只是简单地将烫手山芋扔到调用堆栈上,此时它只能报告给用户和没有以任何有意义的方式处理(如果您相信遵循 OOP 最大的信息隐藏原则,则不会)。

Reference Link: Reference

参考链接: 参考

回答by Johannes

This is how I learned it from "The Big Nerd Ranch Guide (4th edition)":

这是我从“大书呆子牧场指南(第 4 版)”中学到的:

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

回答by Subbu

You can use two methods for raising exception in the try catch block

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

@throw[NSException exceptionWithName];

or the second method

或者第二种方法

NSException e;
[e raise];

回答by R. van Twisk

I believe you should never use Exceptions to control normal program flow. But exceptions should be thrown whenever some value doesn't match a desired value.

我相信你永远不应该使用异常来控制正常的程序流程。但是,只要某个值与所需值不匹配,就应该抛出异常。

For example if some function accepts a value, and that value is never allowed to be nil, then it's fine to trow an exception rather then trying to do something 'smart'...

例如,如果某个函数接受一个值,并且该值永远不允许为零,那么抛出异常而不是尝试做一些“聪明”的事情就可以了……

Ries

里斯