Я пытаюсь написать шаблонную оболочку C ++ вокруг блока и не до конца понимаю, что __bridge
будет иметь в следующем коде:
#if defined(__OBJC__)
#define SAFE_BLOCK_COPY(...) ((__bridge __typeof(__VA_ARGS__))Block_copy((__bridge const void *)(__VA_ARGS__)))
#else
#define SAFE_BLOCK_COPY(Arg) Block_copy(Arg)
#endif
template <typename ReturnType, typename... Args>
struct CppBlock<ReturnType(Args...)>
{
typedef ReturnType (^BlockType)(Args...);
BlockType block;
CppBlock(BlockType inBlock) {
block = SAFE_BLOCK_COPY(inBlock);
}
~CppBlock() {
Block_release(block);
}
ReturnType operator()(Args&&... args) const {
return block(std::forward<Args>(args)...);
}
}
Я создал SAFE_BLOCK_COPY
макрос, так что класс может быть использован как из C ++ & Objective-C ++, as __bridge
недоступен для использования непосредственно из C ++.
Мой вопрос:
Каково влияние добавления __bridge
в этом макросе при компиляции для Objective-C ++? Насколько я понимаю, (__bridge T)
по существу эквивалентно static_cast<T>
так как нет передачи права собственности, генерируемый код должен быть одинаковым независимо от того, вызывается ли он из C ++ или Objective-C.
Есть ли проблемы с классом? Он будет использоваться в одном проекте из Objective-C и C ++.
Если Objective-C использует ARC (а я думаю, что вы используете это, потому что приведения мостов используются, как я полагаю, только в ARC), управление памятью типов указателей объектов Objective-C, включая типы указателей блоков, управляется ARC, и вы не должны ‘ не будет звонить Block_copy
или же Block_release
на них явно.
Вы, вероятно, должны сделать что-то вроде этого:
#if defined(__OBJC__)
#define SAFE_BLOCK_COPY(Arg) (Arg)
#else
#define SAFE_BLOCK_COPY(Arg) Block_copy(Arg)
#endif
#if defined(__OBJC__)
#define SAFE_BLOCK_RELEASE(Arg)
#else
#define SAFE_BLOCK_RELEASE(Arg) Block_release(Arg)
#endif
Других решений пока нет …