【问题标题】:How to create an array of dispatch_block_t in Swift 2.0?如何在 Swift 2.0 中创建一个 dispatch_block_t 数组?
【发布时间】:2024-01-09 17:36:02
【问题描述】:

我在 Swift 1.2 中有一个代码来创建一个 dispatch_block_t 数组,它工作正常。但是相同的代码在 Swift 2.0 中会引发错误。

var menuView: btSimplePopUP!

let actions: [dispatch_block_t] = [{self.pickImages()},
    {self.takePicture()},
    {self.pickVideos()},
    {self.shootVideo()},
    {self.recordAudio()},
    {self.closeView()}]

menuView = btSimplePopUP(itemImage: imgs as [AnyObject],
    andTitles: titles as [AnyObject],
    andActionArray:  actions as NSArray as [AnyObject],
    addToViewController: self)

以上代码在 Swift 1.2 中运行良好。但是在 Swift 2.0 中,它会抛出以下错误

[dispatch_block_t] 不能转换为 NSArray

如何使用 dispatch_block_t 创建 NSArray?

更新:

我已经用下面的代码替换了上面的代码,

let actions: [Any] = [{self.pickImages()},
                    {self.takePicture()},
                    {self.pickVideos()},
                    {self.shootVideo()},
                    {self.recordAudio()},
                    {self.closeView()}]

menuView = btSimplePopUP(itemImage: imgs as [AnyObject],
        andTitles: titles as [AnyObject],
        andActionArray:  actions as! [AnyObject],
        addToViewController: self)

现在,之前的错误消失了。但我在运行时收到以下错误,

致命错误:数组元素无法桥接到 Objective-C

任何帮助将不胜感激。

【问题讨论】:

    标签: ios swift swift2 grand-central-dispatch


    【解决方案1】:
    import XCPlayground
    XCPlaygroundPage.currentPage.needsIndefiniteExecution = false
    
    import Foundation
    
    let a: dispatch_block_t = {
        print("a")
    }
    let b: dispatch_block_t = {
        print("b")
    }
    let arr = [a,b]
    print(arr.dynamicType)
    arr.forEach { (b) -> () in
        b()
    }
    /* prints
    Array<@convention(block) () -> ()>
    a
    b
    */
    class Block {
        var block: dispatch_block_t
        init(block: dispatch_block_t){
            self.block = block
        }
    }
    let block1 = Block(block: a)
    let block2 = Block(block: b)
    
    let arr2: NSArray = [block1,block2]
    print(arr2)
    arr2.forEach { (p) -> () in
        (p as? Block)?.block()
    }
    /* prints
    (
        Block,
        Block
    )
    a
    b
    */
    

    【讨论】:

    • 感谢您的回复。我需要将此数组作为 NSArray 传递给函数。通过时,我收到此错误,“[dispatch_block_t] 不可转换为 NSarray”。任何想法将其作为 NSArray 传递?
    • NSArray 不能保存值类型。为此,您需要将 dispatch_block_t 装箱。查看我的更新答案
    • 谢谢@user3441734 现在,我可以将其转换为 NSArray。但我在函数定义中收到以下错误,*** NSForwarding: warning: object 0x7a5841b0 of class 'ProjName.Block' does not implement methodSignatureForSelector: -- trouble ahead Unrecognized selector -[ProjName.Block copy]
    • 函数定义为,- (instancetype)initWithImage:(UIImage *)image title:(NSString *)title action:(dispatch_block_t)action { if ((self = [super init])) { _title = [title copy]; _imageView = [[UIImageView alloc]initWithImage:image]; _action = [action copy]; } return self; }
    • aha ...所以现在这是一个全新的问题:-)。我要检查你的objc代码的源代码...
    【解决方案2】:

    dispatch_block_t 不是从 AnyObject 继承的,它不是对象。 但是您可以修改您的代码并将AnyObject 更改为Any,如下所示:

    andActionArray : actions as [Any]
    

    它应该适合你。

    更新:

    你的函数接受参数为NSArray,你可以简单地将你的数组转换为这种类型,这段代码在我的快速操场上工作:

    func pickImages() {}
    func takePicture() {}
    func shootVideo() {}
    
    let actions: [dispatch_block_t] = [{pickImages()},
        {takePicture()},
        {shootVideo()}]
    var actionArray: NSArray = actions as NSArray // pass it to the btSimplePopUP init
    

    【讨论】:

    • 感谢您的回复.. 但现在我收到以下错误“[dispatch_block_t] 无法转换为 [Any]”
    • 显示你的btSimplePopUP初始化函数?那里的andActionArray 是什么类型的?没有您的代码,我无法为您提供更多帮助
    • btSimplePopUp 是一个开源的,我用它来显示一个菜单。 init 函数的链接是github.com/balram3429/btSimplePopUp/blob/master/btSimplePopUp/…,init 函数从 Line: 284 开始
    • 我无法将其转换为 NSArray。我收到此错误,“[dispatch_block_t] 无法转换为 NSarray”
    • 请看我更新的问题。我已将操作类型更改为 [Any] 并且我不会收到任何编译时错误。但在运行时,我收到“致命错误:数组元素无法桥接到 Objective-C”