7 Replies
      Latest reply: Jan 9, 2017 3:58 PM by eskimo RSS
      Dogstarsuper Level 1 Level 1 (0 points)


        I created a swift class like this:


        class SwiftClass
            override init()
            static func Test1(closure:()->Void){
            static func Test2(array:[()->Void]){
                for closure in array {


        Both 2 methods wok fine from swift file.




        The function Test1 work fine from objective-c file too.

        [SwiftClass Test1WithClosure:^{
                NSLog(@"SwiftClass Test1") ;
            }] ;


        but Test2 can't be used from objective-c file,the automatically generated -Swift.h file didn't declare it at all.

        @interface SwiftClass : NSObject
        - (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
        + (void)Test1WithClosure:(void (^ _Nonnull)(void))closure;


        Is it possible to call Test2 from objective-c file?

        • Re: Passing an array of closures to a swift method form objectiv-c file
          QuinceyMorris Level 8 Level 8 (5,410 points)

          If you explicitly declare the array-based method as "@objc", you'll get the following compilation error message: "method cannot be marked @objc because the type of the parameter cannot be represented in Objective-C".


          Since you don't get this error with an array of (say) Int, and with a non-array closure parameter, this suggests the compiler could make an @objc-compatible method, but chooses not to try. Or, there may be a technical reason why this array/closure combination can't be represented in Obj-C.


          As a workaround, you could change the Test2 parameter type to [AnyObject], or specify the parameter type as NSArray,  and cast individual elements as the closure type.


          Either way, it's probably worth a bug report, in case this is something that is really supposed to work.

            • Re: Passing an array of closures to a swift method form objectiv-c file
              Dogstarsuper Level 1 Level 1 (0 points)


              I tried the [AnyObject] and NSArray workaround ,

              static func Test3(array:[AnyObject]){
                      for closure in array {
                          (closure as! ()->Void)()

              It build successlly but I got a runtime error

              "Could not cast value of type '__NSGlobalBlock__' (0x1188e9040) to '(()) -> ()' (0x1188ef030)."

              Is there any mistake in the casting?

                • Re: Passing an array of closures to a swift method form objectiv-c file
                  eskimo Apple Staff Apple Staff (8,750 points)

                  The reason why your first attempt didn’t work is that Swift closures and Objective-C blocks are not identical (although they are closely related).  You can get your test2(array:) method exposed to Objective-C by adopting @convention(block), as shown here:

                  typealias Callback = @convention(block) () -> Void
                  class Test : NSObject {
                      class func test2(array: [Callback]) {

                  Or, as you’ve already discovered, using NSArray.  However, the cast required to call the callbacks still fails.  If you expand the above to this:

                  @objc class func test2(array: [Callback]) {
                      for item in array {

                  you get:

                  fatal error: NSArray element failed to match the Swift Array Element type

                  And, as you’ve noted, in the NSArray case, where you have to do an explicit cast, you get a more focused error (even if you use @convention(block)).

                  Unfortunately I was unable to find a way around this, which brings me to the same conclusion as QuinceyMorris: this is definitely worth a bug.

                  Please post your bug number, just for the record.

                  Share and Enjoy

                  Quinn “The Eskimo!”
                  Apple Developer Relations, Developer Technical Support, Core OS/Hardware
                  let myEmail = "eskimo" + "1" + "@apple.com"