加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

Swift尝试在Objective-C块中

发布时间:2020-12-14 04:58:12 所属栏目:百科 来源:网络整理
导读:我需要创建一个函数foo,它将一个抛出闭包作为参数.我可以使用 Swift或ObjC实现它,但我需要能够从两者中调用它. 像这样: // Swiftfunc bar() throwsfunc foo(_ block: () throws - void)foo { try bar()} 和 // Objc[self foo:^( [other barBar];)]; 我尝试
我需要创建一个函数foo,它将一个抛出闭包作为参数.我可以使用 Swift或ObjC实现它,但我需要能够从两者中调用它.

像这样:

// Swift
func bar() throws
func foo(_ block: () throws -> void)

foo {
  try bar()
}

// Objc
[self foo:^(
  [other barBar];
)];

我尝试用Swift和ObjC实现它而没有成功.使用Swift:

@objc
func foo(block: () throws -> Void)

我收到此错误:

Method cannot be marked @objc because the type of the parameter 1 cannot be represented in Objective-C

如果我尝试用ObjC实现它:

typedef BOOL (^ThrowingBlock)(NSError **);
- (void)foo:(ThrowingBlock)block;

然后它不会转换为抛出的块(as it would with a function):

func foo(_: (NSErrorPointer) -> Bool)

知道怎么做到这一点?

解决方法

您可以使用NS_REFINED_FOR_SWIFT宏在Objective-C和Swift之间提供统一的接口,在Objective-C中抛出Swift和NSError **.

从Apple documentation:

You can use the NS_REFINED_FOR_SWIFT macro on an Objective-C method declaration to provide a refined Swift interface in an extension,while keeping the original implementation available to be called from the refined interface. For instance,an Objective-C method that takes one or more pointer arguments could be refined in Swift to return a tuple of values.

在你的情况下,你可以将foo声明为Swift的精炼,并在类扩展中添加相同的方法:

@interface MyClass : NSObject

- (void)foo:(void (^)(NSError **))block NS_REFINED_FOR_SWIFT;

@end

在斯威夫特:

extension MyClass {
    func foo(block: @escaping () throws -> Void) {
        // Objective-C's `foo` is now imported as `__foo`
        __foo { errPtr in
            do {
                try block()
            } catch {
                errPtr?.pointee = error as NSError
            }
        }
    }
}

现在你可以从两个世界调用foo,区别在于Objective-C代码需要传递NSError **块,而Swift调用者可以通过更好的抛出关闭.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读