Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

iOS 5 Blocks ARC bridged cast

This Question references this Question: How to simplify callback logic with a Block?

My header has these typedefs

typedef void (^StuffDoneBlock)(NSDictionary * parsedData);
typedef void (^StuffFailedBlock)(NSError * error);

And in init

stuffDoneCallback = Block_copy(done);
StuffFailedCallback = Block_copy(error);

In this paper its says that Block_copy is unnecessary. But then it needs a bridged cast. The compiler message is at follows:

error: cast of block pointer type 'StuffDoneBlock' (aka 'void (^)(NSDictionary *__strong)') to C pointer type 'const void *' requires a bridged cast [4]
         stuffDoneCallback = _bridge(Block_copy(done));
                                     ^~~~~~~~~~~~~~~~
/Developer-4.2/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator5.0.sdk/usr/include/Block.h:60:61: note: instantiated from:
 #define Block_copy(...) ((__typeof(__VA_ARGS__))_Block_copy((const void *)(__VA_ARGS__)))
                                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~
like image 474
zeiteisen Avatar asked Oct 11 '11 09:10

zeiteisen


1 Answers

First off, why are you even using Block_copy()? Unless you're writing raw C, you should be calling -copy on the block instead, as in [done copy]. Secondly, ARC will copy blocks for you that need to live past their initialization scope[1], so you don't need to even call -copy anymore. The only "exception" is that block-typed properties still need to have the copy attribute.

[1]: Clarification appears to be needed here. ARC only implicitly copies blocks when the compiler sees that it needs to live past its initialization scope. This basically means when it's assigned to a variable that escapes the current scope (stack variable declared in a parent scope, instance variable, static, etc.). However, if it's passed as an argument to a method/function, the compiler does not do any automatic copying. Typically this isn't a problem because block-aware methods/functions that need to hold onto the block past the stack frame (dispatch_async(), completion blocks, etc.) will copy them for you. However, APIs that are not block-aware (such as NSArray) will not implicitly copy the block, since they expect that a simple -retain will do the trick. If you're passing your block to a non-block-aware API and the block needs to live past the current scope, you must use an explicit -copy.

like image 58
Lily Ballard Avatar answered Nov 17 '22 06:11

Lily Ballard