如何调用接受块字典作为来自 Swift 的参数的 objective-c 函数?
How to call an objective-c function which accepts Dictionary of blocks as argument from Swift?
我的 objective c 文件中有一个函数(比方说 class MyBlockExecutor):
+ (void) runBlockFromDictionary: (NSDictionary*) blocksDict andKey: (NSString*) key
{
if ( [blocksDict objectForKey: key] != nil )
{
((MyBlock)[blocksDict objectForKey: key])();
}
}
现在,我想从 Swift 调用这个函数。这是我的 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
我该如何解决这个问题?
编辑:
我对 objective c 函数的变化持开放态度,我只是需要以某种方式将闭包集合从 swift 传递到我的 objective c 函数和 运行 块。
尝试分段分解代码并检查错误来源..虽然它几乎与您所做的相同,但我们只是将代码分解为多行以便于调试
//1. create the block instance separately
let myBlockForKey1:MyBlock = { () in
print("block for key1 called")
}
//2. create dic of blocks as
let dicOfBlocks:[String:MyBlock] = ["key1":myBlockForKey1]
//3. call your function
MyBlockExecutor.runBlock(from: dicOfBlocks, andKey: "key1")
您可以使用与 Swift blocks not working 类似的方法:用 @convention(block)
注释块
使用 Objective-C 块调用约定,并(明确地)强制转换
在将其放入字典之前将其设置为 AnyObject
:
let myBlock: @convention(block) () -> Void = {
print("block for key1 called")
}
let dict = ["key1": myBlock as AnyObject]
MyBlockExecutor.runBlock(from: dict, andKey: "key1")
这在我的测试中按预期工作。
也和奎因的《爱斯基摩人!建议在
the Apple developer forum 作为一种方法
将闭包(在 Swift 中定义)作为 Objective-C 兼容传递
通过指针对象,只是我替换了 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")
我的 objective c 文件中有一个函数(比方说 class MyBlockExecutor):
+ (void) runBlockFromDictionary: (NSDictionary*) blocksDict andKey: (NSString*) key
{
if ( [blocksDict objectForKey: key] != nil )
{
((MyBlock)[blocksDict objectForKey: key])();
}
}
现在,我想从 Swift 调用这个函数。这是我的 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
我该如何解决这个问题?
编辑: 我对 objective c 函数的变化持开放态度,我只是需要以某种方式将闭包集合从 swift 传递到我的 objective c 函数和 运行 块。
尝试分段分解代码并检查错误来源..虽然它几乎与您所做的相同,但我们只是将代码分解为多行以便于调试
//1. create the block instance separately
let myBlockForKey1:MyBlock = { () in
print("block for key1 called")
}
//2. create dic of blocks as
let dicOfBlocks:[String:MyBlock] = ["key1":myBlockForKey1]
//3. call your function
MyBlockExecutor.runBlock(from: dicOfBlocks, andKey: "key1")
您可以使用与 Swift blocks not working 类似的方法:用 @convention(block)
注释块
使用 Objective-C 块调用约定,并(明确地)强制转换
在将其放入字典之前将其设置为 AnyObject
:
let myBlock: @convention(block) () -> Void = {
print("block for key1 called")
}
let dict = ["key1": myBlock as AnyObject]
MyBlockExecutor.runBlock(from: dict, andKey: "key1")
这在我的测试中按预期工作。
也和奎因的《爱斯基摩人!建议在
the Apple developer forum 作为一种方法
将闭包(在 Swift 中定义)作为 Objective-C 兼容传递
通过指针对象,只是我替换了 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")