这个问题引用了这个问题:如何用Block简化回调逻辑?
我的标头有这些 typedef
typedef void (^StuffDoneBlock)(NSDictionary * parsedData);
typedef void (^StuffFailedBlock)(NSError * error);
并且在初始化中
stuffDoneCallback = Block_copy(done);
StuffFailedCallback = Block_copy(error);
在这篇论文中,它说 Block_copy 是不必要的。但接下来它需要一个桥接演员。
编译器消息如下:
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__)))
^~~~~~~~~~~~~~~~~~~~~~~~~~~
首先,你为什么要使用Block_copy()
?除非你正在编写原始 C,否则你应该调用-copy
相反,在块上,如[done copy]
。其次,ARC 将为您复制需要超越其初始化范围的块[1],因此您甚至不需要调用-copy
不再了。唯一的“例外”是块类型属性仍然需要具有copy
属性。
[1]:这里似乎需要澄清。 ARC 仅在以下情况下隐式复制块:编译器看到它需要超越其初始化范围。这基本上意味着当它被分配给一个逃逸当前作用域的变量时(在父作用域中声明的堆栈变量、实例变量、静态变量等)。但是,如果它作为参数传递给方法/函数,编译器不会执行任何自动复制。通常这不是问题,因为块感知方法/函数需要保留超出堆栈帧的块(dispatch_async()
、完成块等)将为您复制它们。然而,APInot块感知(例如NSArray
)不会隐式复制该块,因为他们期望一个简单的-retain
会成功的。如果您将块传递给非块感知 API 并且该块需要超出当前范围,则必须使用显式-copy
.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)