问题描述
我有一个技巧,可以帮助测试在Swift 2.x中工作的UIAlertController
:
I had a trick to help test UIAlertController
that worked in Swift 2.x:
extension UIAlertController {
typealias AlertHandler = @convention(block) (UIAlertAction) -> Void
func tapButtonAtIndex(index: Int) {
let block = actions[index].valueForKey("handler")
let handler = unsafeBitCast(block, AlertHandler.self)
handler(actions[index])
}
}
在带有fatal error: can't unsafeBitCast between types of different sizes
的Swift 3.x下,此操作失败,这使我相信可能有一种方法可以进行强制转换.有人能弄清楚吗?
This fails under Swift 3.x with fatal error: can't unsafeBitCast between types of different sizes
, which tempts me to believe there might be a way to make the cast work. Can anyone figure it out?
推荐答案
找到了可在Swift 3.0.1中使用的解决方案
Found a solution that works in Swift 3.0.1
extension UIAlertController {
typealias AlertHandler = @convention(block) (UIAlertAction) -> Void
func tapButton(atIndex index: Int) {
if let block = actions[index].value(forKey: "handler") {
let blockPtr = UnsafeRawPointer(Unmanaged<AnyObject>.passUnretained(block as AnyObject).toOpaque())
let handler = unsafeBitCast(blockPtr, to: AlertHandler.self)
handler(actions[index])
}
}
}
(最初,block
值是实际的块,而不是指向该块的指针-您显然不能将其转换为指向AlertHandler
的指针)
(Originally, the block
value was the actual block, not a pointer to the block—which you obviously can't cast to a pointer to AlertHandler
)
这篇关于如何在Swift 3中将__NSMallocBlock__转换为其基础类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!