在Objective-C中,我有一个完成块类,定义为:
File.h
typedef void (^MYCompletionBlock)(BOOL success, NSDictionary *result, NSError *error);
然后,在Swift文件中,我尝试使用完成块,如下所示:
Swift.swift
class MyClass: NSObject{
...
func MyFunction() -> Void {
...
objcMethod(param1, withCompletion: {(MYCompletionBlock) -> Void in
if (success){ // Error:"Use of unresolved identifier 'success'"
}
}
...
}
...
}
但是,我一直收到错误:"使用未解析的标识符'成功'"。
我也尝试了以下内容:
objcMethod(param1, withCompletion: {(success:Bool, result: NSDictionary, error:NSError) -> Void in
if (success){ // Error:"Cannot convert value of type '(Bool, NSDictionary, NSError) -> Void' to expected argument type "MYCompletionBlock!"
}
}
有人可以帮我理解如何在Swift中正确指定Obj-C完成块吗?
答案 0 :(得分:4)
鉴于您的闭包没有指定nullability限定符(它们几乎肯定是可选的),可以安全地假设您的Objective-C API尚未经过可空性审核。因此,Swift会将指针视为隐式解包的选项。此外,现在NSDictionary
被映射到[NSObject : AnyObject]
Swift词典。
因此,它将是:
obj.objcMethod(param) { (success: Bool, result: [NSObject : AnyObject]!, error: NSError!) in
if success {
// do something
}
}
或者,正如Kobi指出的那样,您可以让编译器推断出类型:
obj.objcMethod(param) { success, result, error in
if success {
// do something
}
}
注意,您不必自己记住这一点。输入代码时,您可以利用Xcode的代码完成。因此,输入足够的内容以匹配方法名称,并在匹配objcMethod
时,然后按Enter键:
当你到达MYCompletionBlock
时,再次按回车键,它会显示正确的签名:
如果这个Objective-C方法是我自己的类,我会审核它的可空性。因此,例如,我们假设param
是可选的,需要关闭,result
和error
是可选的,您可以这样定义:
NS_ASSUME_NONNULL_BEGIN
typedef void (^MYCompletionBlock)(BOOL success, NSDictionary * _Nullable result, NSError * _Nullable error);
@interface MyObject : NSObject
- (void)objcMethod:(NSDictionary * _Nullable)param1 withCompletionHandler:(MYCompletionBlock)completionHandler;
@end
NS_ASSUME_NONNULL_END
而且,如果是这种情况,你的Swift代码就会这样称呼它:
obj.objcMethod(param) { (success: Bool, result: [NSObject : AnyObject]?, error: NSError?) in
if success {
// do something
}
}
或者,再次,让编译器为您推断类型(但这次它们被推断为未隐式解包的选项):
obj.objcMethod(param) { success, result, error in
if success {
// do something
}
}
答案 1 :(得分:3)
您不应该为完成块参数指定类型,因为某些类型在Swift和Objective C之间推迟(例如BOOL
在Swift中实际上是ObjCBool
。
这应该有效:
objcMethod(param1) { (success, result, error) in
if (success){
// Do something
}
}