开发者

iOS 5 Blocks ARC bridged cast

开发者 https://www.devze.com 2023-04-11 23:19 出处:网络
This Question references this Question: How to simplify callback logic with a Block? My header has these typedefs

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

My header has these typedefs

typedef void (^StuffDoneBlock)(NSDictionary 开发者_C百科* 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__)))
                                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号