[SR-2932] Swift unconditionally bridges obj-c parameters to blocks even when they're ignored #45526
Labels
bug
A deviation from expected or documented behavior. Also: expected but undesirable behavior.
compiler
The Swift compiler in itself
crash
Bug: A crash, i.e., an abnormal termination of software
regression
run-time crash
Bug → crash: Swift code crashed during execution
swift 3.0
Attachment: Download
Environment
Apple Swift version 3.0 (swiftlang-800.0.46.2 clang-800.0.38)
Target: x86_64-apple-macosx10.9
Additional Detail from JIRA
md5: 2d06175c0679d4dcddde6c516d2572d6
Issue Description:
When Obj-C declares a completion block that takes e.g. an NSDictionary, and Swift code provides the closure, the compiler automatically bridges the parameters from Obj-C to Swift, turning that NSDictionary into
[AnyHashable: Any]
(or in Swift 2.3,[NSObject: AnyObject]
). In Swift 2.3, if the block ignores the parameter, this bridging does not actually happen. In Swift 3.0, it happens even though the parameter is unused. Not only is this unnecessary work that can adversely affect performance, it's also a potential crash if the Obj-C code passes an object of the wrong type to the block (which is what actually happened in our app).I've attached an Xcode project demonstrating this. It declares an Obj-C class that accepts a completion block, and it passes an object of the wrong type to the completion block. It has schemes for both Swift 2.3 and Swift 3.0. In Swift 2.3, the program executes just fine (since it ignores the parameter). In Swift 3.0 it crashes in
Dictionary._unconditionallyBridgeFromObjectiveC
because it's sending an unrecognized selector to NSData. The Swift code looks likeThe text was updated successfully, but these errors were encountered: