Uploaded image for project: 'Swift'
  1. Swift
  2. SR-6873

Can't use Swift closure as ObjC block type (Any type)

    XMLWordPrintable

    Details

    • Type: Bug
    • Status: Open
    • Priority: Medium
    • Resolution: Unresolved
    • Component/s: Compiler
    • Labels:
      None
    • Environment:

      Xcode 9.2, Swift 4.0.3

      Description

      Consider this ObjC block:

      typedef void (^PSPDFRenderDrawBlock)(CGContextRef context, NSUInteger page, CGRect cropBox, NSUInteger rotation, NSDictionary<NSString *, id> *_Nullable options);

      that is imported to Swift as (notice no @convention(block) here)

      public typealias PSPDFRenderDrawBlock = (CGContext, UInt, CGRect, UInt, [String : Any]?) -> Swift.Void

      and stored in Dictionary on Swift side:

      let renderDrawBlock: PSPDFRenderDrawBlock = { context, page, cropBox, _, _ in
          // body
      }
      
      let dict: [String: Any] = ["foo": renderDrawBlock]
      

      next, the `dict` is passed to the ObjC method as an argument of `NSDictionary<NSString, id>` type.

      So far so good, everything compiles and works.

      Now, when I try to retrieve the closure on the ObjC side and use it (call it). It crashes in runtime.

      auto value = dictionary[@"foo"]; // _SwiftValue *
      

      now, trying to use `value` it will crash of course.

      The known workaround is to specify @convention(block) manually and unsafeBitCast() to AnyObject. See: https://stackoverflow.com/a/32787157/699944 for complete problem and example

        Attachments

          Activity

            People

            • Assignee:
              Unassigned
              Reporter:
              krzyzanowskim Marcin Krzyzanowski
            • Votes:
              0 Vote for this issue
              Watchers:
              5 Start watching this issue

              Dates

              • Created:
                Updated: