8

Swift 2.xで機能するテストを支援するトリックがありました:UIAlertController

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])
    }

}

これは Swift 3.x で失敗しますfatal error: can't unsafeBitCast between types of different sizes。誰でもそれを理解できますか?

4

3 に答える 3

22

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) 。

于 2016-11-16T14:33:15.523 に答える