如何在 Swift2 中使用 ObjC 块类型定义(尤其是当包含 BOOL 参数时)

How to use ObjC block typedefs in Swift2 (esp. when containing BOOL parameters)

继续使用 Xcode7 (beta5) 和 Swift 2 后,我的 Swift 代码出现了关于 Bool(或 BOOL / ObjCBool) 使用 Objective-C typedef.

从(或进入)闭包传递的值
typedef void (^completion_success_block_t) (BOOL success);

当我在 Swift class 中使用此类型时,出现编译器错误。

func doSomething(completionBlock : completion_success_block_t) {
    doSomethingElse { success in
        if success == true { } // (1) error 1
        let foo : Bool = true
        completionBlock(foo) // (2) error 2
        completionBlock(true) // (3) works just fine! 
    }
}
// error 1: "Binary operator '==' cannot be applied to operands of type 'ObjCBool' and 'Bool'"
// error 2: "Cannot invoke 'completionBlock' with an argument list of type '(Bool)'"

func doSomethingElse(completionBlock : completion_success_block_t) {
    completionBlock(true)
} 

为什么第 (3) 行编译得很好,而不是第 (2) 行? 在某些情况下,编译器似乎确实在 ObjCBools 和 Bools 之间转换,但并非总是如此。

感觉就像使用我的 ObjC typedef 就像告诉编译器:'我真的希望这是一个 ObjCBool,而不是 Bool,所以请不要这样做我的任何转换'。但这不是我想要的。我的代码在 Xcode 6.

中运行良好

现在我只看到两个选项:

1) 在传递/使用它们之前手动转换所有值:let swiftSuccess = Bool(success)let objCFoo = ObjCBool(foo)

2) 停止对包含 BOOL 参数的块使用 ObjC typedefs

有没有更好的方法?也许更改 typedef 中的块签名以与 Swift 和 ObjC 一起工作?但是怎么办?

酷! Apple 在 Xcode 版本 7.0 (7A218) 中修复了此问题。现在将 Swift Bool 传递给一个带有 BOOL 参数的 ObjC typedef 闭包就可以正常工作了。将 BOOL 参数与 Swift 中的 truefalse 进行比较同样有效。

对我来说唯一的缺点是:现在我所有的变通代码行(例如 completionBlock(ObjCBool(true)))都会导致编译器错误(有时甚至是稍微晦涩的 Segmentation fault: 11 类型)。必须全部还原。唉...(谢天谢地还有git)