Какой является правильным, ноль или NULL, чтобы пометить «нет блока Objective-C»? - PullRequest
63 голосов
/ 23 апреля 2011

Если я не хочу ничего передавать для блока Objective C, какое ключевое слово мне следует использовать, NULL или nil? Я спрашиваю об этом, потому что блок Objective C является объектом Objective C (как я знаю), но представлен как указатель на функцию.

NULL и nil оба указывают указатель 0x0, однако они семантически различаются. Так что я обеспокоен этим.

1 Ответ

83 голосов
/ 23 апреля 2011

Блоки не представлены как указатели на функции.Они представлены в виде блоков, и это обозначается символом ^ в их объявлении.Под капотом единственное сходство - синтаксис вызова.В противном случае они оба очень, очень разные.

Часто полезно вызывать методы для них.Например, если вы не используете сборщик мусора, вам нужно , чтобы вызвать метод copy для блоков, если вы хотите сохранить их на потом.С появлением автоматического сохранения количества это даже единственный способ скопировать блок, поскольку правила приведения указателя ARC не позволяют использовать макрос Block_copy.

NULL в зависимости от вашего компилятора,либо просто 0, либо (void*)0.Это будет работать для любого вида указателя.Однако из-за языковых правил Objective-C вы получите предупреждение, если попытаетесь отправить сообщение типу, который не может быть приведен непосредственно к id (и ошибку, если вы используете ARC).

Поскольку отправка сообщений в блоки может быть полезной, для них следует использовать nil.


[РЕДАКТИРОВАТЬ] Давайте поясним, что использование nil или NULLрезультат в точно такой же двоичный код.Ваш выбор константы, вероятно, должен быть основан на том, считаете ли вы блоки объектами Objective-C или нет.Это было гораздо сложнее в те дни, когда вам приходилось писать собственные вызовы retain и release, но теперь ARC выполняет всю работу по управлению памятью за вас.

Если вы использовали блоки раньшеARC была вещь, вы, вероятно, думаете, что это объекты Objective-C.Если нет, то вы, вероятно, не думаете / не понимаете, что они есть.Есть еще несколько реликвий их идентичности в языке (например, вы можете иметь указатель __weak или __unsafe_unretained на блок), но по большей части разница незначительна.Выберите один и попытайтесь придерживаться его.Мне нравится думать о своих блоках как об объектах Objective-C.

...