Компактное отключение предупреждения о циклах сохранения дуги для самореференционных блоков

Я пишу API, который включает обработку событий, и я хотел бы иметь возможность использовать блоки для обработчиков. Обратные вызовы часто хотят получить доступ или изменить себя. В режиме ARC Clang предупреждает, что блоки, ссылающиеся на себя, могут создать цикл сохранения, что кажется полезным предупреждением, которое я хочу сохранить в целом.

Однако для этой части моего API жизненный цикл обратного вызова и содержащий объект поддерживается извне. Я знаю, что могу разорвать цикл, когда объект должен быть освобожден.

Я могу отключить предупреждение цикла сохранения для каждого файла с помощью #pragma clang диагностика игнорируется «-Warc-keep-Cycle» , но это отключает предупреждение для всего файла. Я могу окружить блоки диагностическим нажатием #pragma clang и pop вокруг этого предупреждения, но это делает блоки некрасивыми.

Я также могу получить предупреждение об уходе, указав __weak переменную, указывающую на self, вместо того, чтобы напрямую ссылаться на self, но это делает блоки гораздо менее приятными в использовании.

Лучшее решение, которое я придумал, - это макрос, который выполняет диагностическое отключение вокруг блока:

#define OBSERVE(OBJ, OBSERVEE, PATH, CODE) \
[(OBJ) observeObject:(OBSERVEE) forKeyPath:(PATH) withBlock:^(id obj, NSDictionary *change) { \
_Pragma("clang diagnostic push") \
_Pragma("clang diagnostic ignored \"-Warc-retain-cycles\"") \
do { CODE; } while(0); \
_Pragma("clang diagnostic pop") \
}];

Он работает, но не очень заметен для пользователей API, не допускает вложенных наблюдателей и взаимодействует с плохо с редактором XCode.Есть ли лучший способ отключить или избежать предупреждения?

15
задан Charlie Groves 24 November 2011 в 01:11
поделиться