iOS 5 блокирует ARC мостового броска - PullRequest
9 голосов
/ 11 октября 2011

Этот вопрос ссылается на этот вопрос: Как упростить логику обратного вызова с помощью блока?

В моем заголовке есть эти typedefs

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

и в init

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__)))
                                                             ^~~~~~~~~~~~~~~~~~~~~~~~~~~

1 Ответ

22 голосов
/ 12 октября 2011

Во-первых, почему вы даже используете Block_copy()?Если вы не пишете сырой C, вы должны вместо этого вызывать -copy в блоке, как в [done copy].Во-вторых, ARC будет копировать блоки для вас, которым нужно дойти до их области инициализации [1], поэтому вам даже не нужно даже вызывать -copy.Единственное «исключение» заключается в том, что свойства блочного типа все еще должны иметь атрибут copy.

[1]: здесь требуется пояснение.ARC неявно копирует блоки только тогда, когда компилятор видит, что ему нужно пройти за пределы своей области инициализации.Это в основном означает, когда она назначается переменной, которая выходит за пределы текущей области (переменная стека, объявленная в родительской области, переменная экземпляра, статическая переменная и т. Д.).Однако, если он передается в качестве аргумента методу / функции, компилятор не выполняет автоматического копирования.Как правило, это не проблема, потому что методы / функции с поддержкой блоков, которые должны удерживать блок за кадром стека (dispatch_async(), блоки завершения и т. Д.), Скопируют их для вас.Однако API, которые не осведомлены о блоке (например, NSArray), не будут неявно копировать блок, так как они ожидают, что простой -retain сделает свое дело.Если вы передаете свой блок API, не поддерживающему блокировку, и блок должен жить за пределами текущей области, вы должны использовать явный -copy.

...