【问题标题】:Convert Swift 2 closure to Objective-C block将 Swift 2 闭包转换为 Objective-C 块
【发布时间】:2016-02-12 12:11:13
【问题描述】:

我正在尝试在 Swift 2 中构建一个 Objective-C 块,以便像这样将其添加到 NSArray

typealias CompletionBlock = () -> Void
let aBlock:CompletionBlock =  {
    print("Hello world!")
}
let nsArray = NSMutableArray()
nsArray.addObject(aBlock) // Error

我知道它适用于 Swift 数组,但我需要一个 NSArray 以与现有的 Objective-C 代码兼容。如果我使用 swift 数组,编译器将拒绝将其转换为 NSArray,因为它不会是 [AnyObject](它将是 [Any])。

这里的问题是 swift 闭包不是一个与 Objective-C 块相反的对象,后者是场景背后的对象(它们是 NSBlock 的实例,它是 NSObject 的子类)

所以我的问题是:如何快速创建一个 Objective-C 块?我尝试在 typealias 中使用 @convention (block),但它不起作用。

【问题讨论】:

标签: objective-c swift2 closures objective-c-blocks


【解决方案1】:

编辑: 从 Swift 3 开始,这是完全没有必要的(甚至不起作用)。在 Swift 3 中向 Objective-C 数组添加闭包是开箱即用的。下面的答案仅对 Swift 2 有效。

我知道这是重复的,但我仍会发布来自 swift-closure-as-anyobjectcast-closures-blocks 的重构答案,以防有人首先登陆。

解决方案是使用 unsafeBitCast 函数将 Swift 闭包转换为与 Objective-C 兼容的对象,然后再将其添加到 NSArray 并在 Swift 中使用它之前返回。

// The `@convention(block)` is important here in order to get
// Objective-C like memory management
typealias CompletionBlock = @convention(block) () -> Void

let aBlock:CompletionBlock = {
    print("Hello world!")
}
let nsArray = NSMutableArray()
let blockObject = unsafeBitCast(aBlock, AnyObject.self)
nsArray.addObject(blockObject)

let closureObject = nsArray[0]
let closure = unsafeBitCast(closureObject, CompletionBlock.self)
closure()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-15
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多