Xavier Shay
Xavier Shay

Reputation: 4127

How to call dispatch_block_t directly?

I am trying to update some code for XCode 6.1 / Yosemite. It's a bit weird because it's a macro, but essentially it looks like:

dispatch_block_t blk = ^{ [[self globalEventsHandler] someMethod self]; };
if([NSThread isMainThread]) blk();
else dispatch_async(dispatch_get_main_queue(), blk);

This is causing compilation problems. I have already set OS_OBJECT_USE_OBJC=0 per GCD guide in my preprocessor settings, since right now I'm not interested in modernizing the code.

The first is Implicit conversion of block pointer type 'void (^)(void)' to C pointer type 'dispatch_block_t' (aka 'void *') requires a bridged cast. I can accept the suggest fix for this and get:

dispatch_block_t blk = (__bridge dispatch_block_t)^{ [[self globalEventsHandler] someMethod self]; };
if([NSThread isMainThread]) blk();
else dispatch_async(dispatch_get_main_queue(), blk);

but now I get a new error: Called object type 'dispatch_block_t' (aka 'void *') is not a function or function pointer. And on that I'm stuck.

Questions:

  1. Is there a way to call dispatch_block_t directly now? I have found the original code pattern in a few older blog posts, so I suspect it is (was) common.
  2. Is __bridge the correct way to do this? There seem to be other options related to dispatch_retain and friends that may be appropriate.
  3. I feel like I'm missing a fundamental concept here, which would be very likely since I'm quite inexperienced with OSX development.

For bonus points: how would you get this working without disabling OS_OBJECT_USE_OBJC?

Upvotes: 2

Views: 1968

Answers (1)

Kazuki Sakamoto
Kazuki Sakamoto

Reputation: 14009

That code snippet is totally ok with Xcode 6.1 with OS X SDK 10.10. However, these compile error messages are odd.

Implicit conversion of block pointer type 'void (^)(void)' to C pointer type 'dispatch_block_t' (aka 'void *') requires a bridged cast

Called object type 'dispatch_block_t' (aka 'void *') is not a function or function pointer.

dispatch_block_t should be the following in dispatch/object.h.

typedef void (^dispatch_block_t)(void);

But these error messages say dispatch_block_t is the same as void *. Did you typedef dispatch_block_t yourself instead of including Foundation/Foundation.h or dispatch/dispatch.h? You'd better search dispatch_block_t typedef in your code.

Upvotes: 6

Related Questions