How to call an objective-c function which accepts Dictionary of blocks as argument from Swift?

旧街凉风 提交于 2019-12-01 00:32:26

You can use a similar approach as in Swift blocks not working: Annotate the block with @convention(block) to use the Objective-C block calling convention, and (explicitly) cast it to AnyObject before putting it into the dictionary:

let myBlock: @convention(block) () -> Void = {
    print("block for key1 called")
}

let dict = ["key1": myBlock as AnyObject]

MyBlockExecutor.runBlock(from: dict, andKey: "key1")

This worked as expected in my test.

It is also similar to what Quinn “The Eskimo!” suggested in the Apple developer forum as a method to pass a closure (defined in Swift) as an Objective-C compatible object through pointers, only that I replaced the unsafeBitCast by the simpler as AnyObject.

You can also write everything inline:

MyBlockExecutor.runBlock(from: ["key1": {
        print("block for key1 called")
    } as @convention(block) () -> Void as AnyObject
    ], andKey: "key1")

or define a helper function:

func objcBlock(from block: @convention(block) () -> Void) -> AnyObject {
    return block as AnyObject
}

MyBlockExecutor.runBlock(from: ["key1": objcBlock {
        print("block for key1 called")
    }], andKey: "key1")

try to break the code in segments and check from where the error is coming.. although its nearly same what you have done we have just break the code in multiple line for debugging easily

//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")
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!