我的目标c文件中有一个函数(比如说MyBlockExecutor类):
+ (void) runBlockFromDictionary: (NSDictionary*) blocksDict andKey: (NSString*) key { if ( [blocksDict objectForKey: key] != nil ) { ((MyBlock)[blocksDict objectForKey: key])(); } }
现在,我想从Swift调用此函数。这是我的快速电话:
MyBlockExecutor.runBlock(from: [ "key1":{ ()->Void in print("block for key1 called") } ], andKey: "key1")
这会使我的应用程序崩溃。我在这条线上收到EXC_BAD_ACCESS错误:
((MyBlock)[blocksDict objectForKey: key])();
虽然,从Objective-C调用相同的功能非常好。另外,我将MyBlock定义为:
typedef void (^MyBlock)(); //defined in MyBlockExecutor.h file
我该如何解决?
编辑:我对目标c函数的更改持开放态度,我只是需要以某种方式将闭包的集合从swift传递到我的目标c函数并运行该块。
您可以使用与Swift块不起作用类似的方法:@convention(block) 使用Objective- C块调用约定对块进行注释,并(明确地)将其AnyObject强制转换为字典之前:
@convention(block)
AnyObject
let myBlock: @convention(block) () -> Void = { print("block for key1 called") } let dict = ["key1": myBlock as AnyObject] MyBlockExecutor.runBlock(from: dict, andKey: "key1")
这按我的测试预期工作。
它也类似于奎因的《爱斯基摩人》。在Apple开发人员论坛中建议 将其作为通过指针传递闭包(在Swift中定义)作为与Objective-C兼容的对象的方法,只有我用unsafeBitCast 更简单的代替了as AnyObject。
unsafeBitCast
as AnyObject
您还可以内联编写所有内容:
MyBlockExecutor.runBlock(from: ["key1": { print("block for key1 called") } as @convention(block) () -> Void as AnyObject ], andKey: "key1")
或定义一个辅助函数:
func objcBlock(from block: @convention(block) () -> Void) -> AnyObject { return block as AnyObject } MyBlockExecutor.runBlock(from: ["key1": objcBlock { print("block for key1 called") }], andKey: "key1")