I had a trick to help test UIAlertController that worked in Swift 2.x:
extension UIAlertController {
typealias AlertHandler = @convention(b
My answer is based on @Robert Atkins's, but shorter.
The problem here is that, valueForKey returns a Any typed object, and because in Swift,
MemoryLayout.size == 32
MemoryLayout.size == 8
an assertion will be triggered in unsafeBitCast when casting between types of different sizes.
One work-around is to create an intermediate wrapper and transform back to raw pointer, which satisfies MemoryLayout.
A much simpler way is to create an indirect reference directly using protocol AnyObject, relying on the fact that MemoryLayout, we can write following valid code:
typealias AlertHandler = @convention(block) (UIAlertAction) -> Void
func tapButton(atIndex index: Int) {
if let block = actions[index].value(forKey: "handler") {
let handler = unsafeBitCast(block as AnyObject, to: AlertHandler.self)
handler(actions[index])
}
}