将 Swift 2 闭包转换为 Objective-C 块
Convert Swift 2 closure to Objective-C block
我正在尝试在 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
的实例,是 NSBlock
的子类NSObject
)
所以我的问题是:如何在 swift 中创建 Objective-C 块?我试过在 typealias 中使用 @convention (block)
但它不起作用。
编辑: 从 Swift 3 开始,这是完全没有必要的(甚至不起作用)。向 Objective-C 数组添加闭包在 Swift 3 中开箱即用。下面的答案仅对 Swift 2 有效。
我知道这是重复的,但我仍然会 post 来自 and cast-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()
我正在尝试在 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
的实例,是 NSBlock
的子类NSObject
)
所以我的问题是:如何在 swift 中创建 Objective-C 块?我试过在 typealias 中使用 @convention (block)
但它不起作用。
编辑: 从 Swift 3 开始,这是完全没有必要的(甚至不起作用)。向 Objective-C 数组添加闭包在 Swift 3 中开箱即用。下面的答案仅对 Swift 2 有效。
我知道这是重复的,但我仍然会 post 来自
解决方案是使用 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()