Swift不会将Objective-C NSError **转换为throws [英] Swift doesn't convert Objective-C NSError** to throws

查看:75
本文介绍了Swift不会将Objective-C NSError **转换为throws的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一些Objective-C遗留代码,声明方法如

I have some Objective-C legacy code, that declares method like

- (void)doSomethingWithArgument:(ArgType)argument error:(NSError **)error

如此处所写 https://developer.apple.com/library/ios/documentation/Swift/Conceptual/BuildingCocoaApps/AdoptingCocoaDesignPatterns .html


Swift自动将产生错误
的Objective-C方法转换为根据以下方法抛出错误的方法Swift的原生错误
处理功能。

Swift automatically translates Objective-C methods that produce errors into methods that throw an error according to Swift’s native error handling functionality.

但在我的项目中描述的方法是这样调用的:

But in my project described methods are called like this:

object.doSomething(argument: ArgType, error: NSErrorPointer)

此外,当我尝试使用它们时会抛出运行时异常:

Moreover, it throws runtime exception when I try to use them like:

let errorPtr = NSErrorPointer()
object.doSomething(argumentValue, error: errorPtr)

我是否还需要更多东西来将Objective-CNSError **方法转换为Swifttrows方法?

Do I need something more to convert Objective-C "NSError **" methods to Swift "trows" methods?

推荐答案

只返回 BOOL 或(可为空)对象
的Objective-C方法转换为throw Swift中的方法。

Only Objective-C methods which return a BOOL or a (nullable) object are translated to throwing methods in Swift.

原因是Cocoa方法总是使用返回值 NO nil
表示方法失败,而只是设置错误对象。
这记录在
使用和创建错误对象

The reason is that Cocoa methods always use a return value NO or nil to indicate the failure of a method, and not just set an error object. This is documented in Using and Creating Error Objects:


重要提示:返回表示成功或失败方法的价值。
虽然在Cocoa错误
域中间接返回错误对象的Cocoa方法保证返回此类对象,如果方法通过直接返回nil或NO指示失败
,则应始终检查返回在尝试对NSError对象执行任何操作之前,
值为nil或NO。

Important: Success or failure is indicated by the return value of the method. Although Cocoa methods that indirectly return error objects in the Cocoa error domain are guaranteed to return such objects if the method indicates failure by directly returning nil or NO, you should always check that the return value is nil or NO before attempting to do anything with the NSError object.

例如,Objective-C接口

For example, the Objective-C interface

@interface OClass : NSObject

NS_ASSUME_NONNULL_BEGIN

-(void)doSomethingWithArgument1:(int) x error:(NSError **)error;
-(BOOL)doSomethingWithArgument2:(int) x error:(NSError **)error;
-(NSString *)doSomethingWithArgument3:(int) x error:(NSError **)error;
-(NSString * _Nullable)doSomethingWithArgument4:(int) x error:(NSError **)error;

NS_ASSUME_NONNULL_END

@end

已映射to Swift as

is mapped to Swift as

public class OClass : NSObject {

    public func doSomethingWithArgument1(x: Int32, error: NSErrorPointer)
    public func doSomethingWithArgument2(x: Int32) throws
    public func doSomethingWithArgument3(x: Int32, error: NSErrorPointer) -> String
    public func doSomethingWithArgument4(x: Int32) throws -> String
}

如果你可以改变方法的接口,那么你应该添加一个布尔值
返回值表示成功或失败。

If you can change the interface of your method then you should add a boolean return value to indicate success or failure.

否则你将从Swift中调用它

Otherwise you would call it from Swift as

var error : NSError?
object.doSomethingWithArgument(argumentValue, error: &error)
if let theError = error {
    print(theError)
}

备注:

  • https://github.com/apple/swift/blob/master/test/Inputs/clang-importer-sdk/usr/include/errors.h

我发现Clang有一个属性强制函数在Swift中抛出错误:

I found that Clang has an attribute which forces a function to throw an error in Swift:

-(void)doSomethingWithArgument5:(int) x error:(NSError **)error
  __attribute__((swift_error(nonnull_error)));

映射到Swift为

public func doSomethingWithArgument5(x: Int32) throws

似乎工作正常如预期的那样。但是,我找不到关于此属性的任何官方文档
,所以依赖它可能不是一个好主意。

and seems to work "as expected". However, I could not find any official documentation about this attribute, so it might not be a good idea to rely on it.

这篇关于Swift不会将Objective-C NSError **转换为throws的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆