1

My Swift 3.0 project uses an Objective-C library that defines a certain type (AsyncBlock) as an Obj-C block:

typedef BOOL (^AsyncBlock)(id __nullable * __nonnull context);

In Swift 3.0 terms, that should translate into a non optional pointer to an optional value, so I figured I should be able to assign a variable of type AsyncBlock to a closure defined in my swift 3 project as follows (not including bridging header and other details for brevity):

func closure(_ context: UnsafeMutablePointer<Any?>) -> Bool { return true } var myClosureVariable: AsyncBlock = closure

The compiler disagrees: Cannot assign value of type '(UnsafeMutablePointer<Any?>) -> Bool' to type 'AsyncBlock' - what am I doing wrong?

Hugo
  • 974
  • 9
  • 21

1 Answers1

0

An Obj-C id normally maps to a Swift 3.0 Any, but here we have to use AnyObject (not sure why). Also we need to use an AutoreleasingUnsafeMutablePointer instead of an UnsafeMutablePointer (again, not clear as to the reasons why)

This works:

func closure(_ context: AutoreleasingUnsafeMutablePointer<AnyObject?>) -> Bool { return true } var myClosureVariable: AsyncBlock = closure

Hugo
  • 974
  • 9
  • 21
  • Objective-C's ARC has to be compatible with manual reference counting. Passing an indirect pointer it is not clear, how that behaves inside the called block, function, method or whatever. There is a convention, that it is passed autoreleased. i. e. http://stackoverflow.com/questions/8862023/in-which-situations-do-we-need-to-write-the-autoreleasing-ownership-qualifier – Amin Negm-Awad Nov 10 '16 at 05:45