Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/319.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将Java代码移植到ObjC时,如何最好地表示已检查的异常?_Java_Objective C_Cocoa_Macos_Porting - Fatal编程技术网

将Java代码移植到ObjC时,如何最好地表示已检查的异常?

将Java代码移植到ObjC时,如何最好地表示已检查的异常?,java,objective-c,cocoa,macos,porting,Java,Objective C,Cocoa,Macos,Porting,我正在致力于将Java代码库移植到Cocoa/Objective-C,以便在桌面Mac OS X上使用。Java代码有很多方法,其中有检查过的异常,如: double asNumber() throws FooException { ... } 在Objective-C中表示这些的最佳方式是什么?异常或错误输出参数 - (CGFloat)asNumber { ... // possibly [FooException raise:format:]; } 或 我觉得对于Obj

我正在致力于将Java代码库移植到Cocoa/Objective-C,以便在桌面Mac OS X上使用。Java代码有很多方法,其中有检查过的异常,如:

double asNumber() throws FooException {
    ...
}
在Objective-C中表示这些的最佳方式是什么?异常或错误输出参数

- (CGFloat)asNumber { 
    ... // possibly [FooException raise:format:];
}

我觉得对于Objective-C,输出错误通常是更好的解决方案,但正如您所看到的。。。很多像上面这样的方法看起来会很尴尬。再说一次,有很多这样的

当然,请记住,因为这些是Java中检查的异常,所以我需要添加
@try
块或
if(*outError){…}
检查调用这些方法的任何地方(很多地方)


我记得听说,在Objective-C中输入
@try
块曾经很昂贵,但在64位、SL或其他一些新的env中却很便宜(记不清了)。我一点也不担心向后兼容性,所以我绝对愿意只为新的热点进行设计。

异常可能是最好的方法,因为64位Obj-C ABI(运行时)使用零成本异常,因此您可以获得更干净的代码,而无需实际成本。当然,在32位中,旧的SETJMP/LangJMP异常仍然在使用,它们不与C++交互,所以如果这是一个目标,那么你就有问题了。

< P>你正确地指出“OUT错误通常是Objc更好的解决方案”。在Cocoa中很少会发现抛出异常的API(除非您没有满足API的先决条件,但在这种情况下,默认情况下行为是未定义的)


如果您希望此代码超出您的范围,并被其他Cocoa开发人员采用,我建议使用out错误。我从事的代码是由不熟悉Cocoa的人编写的,他们大量使用异常,解决这些问题非常困难。

对于从字符串解析数字之类的事情,你应该绝对避免异常。在Objective-C中,异常表示程序员错误,而不是用户输入错误,甚至是不可用的文件。(部分原因是异常处理总是比更“常规”的错误处理成本更高、更复杂。尽管如此,每当实际引发异常时,异常处理仍然很慢。)当然,您可以随意使用异常,但这不是Cocoa方法,您会发现自己与其他Objective-C代码不一致。使用您的代码的人会非常恼火,因为您在只会导致错误的情况下抛出异常

发件人:

“在许多环境中,异常的使用相当普遍。例如,您可能会抛出异常以表示例程无法正常执行,例如当文件丢失或数据无法正确解析时。在Objective-C中,异常是资源密集型的。您不应该将异常用于常规流控制,或者仅仅表示错误。相反,您应该使用方法或函数的返回值来指示发生了错误,并在错误对象中提供有关问题的信息。”

看看内置的Cocoa类如何处理这样的错误。例如,有一些方法,如
-floatValue
,如果失败则返回0。针对您的特定情况,更好的解决方案可能是如何处理,例如在
-scanFloat:
-接受指向结果应存储的字段的指针,然后返回
YES
NO
,取决于解析是否成功

除了Obejctive-C约定和最佳实践之外,NSError比NSException更健壮、更灵活,并且允许调用方有效地忽略问题(如果他们愿意)。我建议通读。注意:如果您接受
NSError**
参数,我强烈建议您也设计为允许客户端如果他们不想接收任何错误信息,请传递
NULL
。我知道的每个Cocoa类都会针对错误执行此操作,包括NSString


虽然移植的代码可能最终看起来与Java代码完全不同,但要认识到它将被Objective-C代码使用,而不是Java等价物的相同客户端。绝对符合语言的习惯用法。端口不会是Java代码的镜像,但它会更正确(对于Objective-C)因此。

在Cocoa中,异常实际上只用于“编程错误”;“其原理是让应用程序捕捉到它们,让用户选择保存它们正在做的事情,然后退出。首先,并非所有框架或代码路径都是100%异常安全的,因此这可能是唯一安全的操作过程。对于可以预期并从中恢复的错误,您应该使用NSError,通常是通过out参数

我非常喜欢Objective-C使用的out-error方法。你必须处理异常,但如果你愿意,你可以选择忽略out-error。这完全符合Objective-C的态度,即“程序员知道他们在做什么”。“它还使Objective-C成为一种外观非常干净的语言,因为您的代码中没有try-catch块


也就是说,您可能需要考虑:是否存在忽略异常的场景?您抛出的异常是否真正重要?您是否发现自己正在编写简单的catch块来清理变量并继续?我倾向于输出错误,因为我喜欢语法,Objective-C只为最关键的错误保留异常。

看起来这些已检查的异常更清晰地映射到输出错误。例外情况仍然可以使用,但应保留在特殊情况下。

thx用于伟大的反馈oliver。对于记录,不,我不会把这个代码库和C++以任何方式混合。- 1抱歉,但是这是对Objy-C的可怕建议。不是所有的例外都是“零成本”,而不是那些从未真正发生过的。
- (CGFloat)asNumberError:(NSError **)outError {
    ...
}