Использование __attribute __ в коде, управляемом ARC - PullRequest
2 голосов
/ 01 октября 2011

Когда ARC пришел к Objective-C, я приложил все усилия, чтобы прочитать руководство Objective-C Автоматический подсчет ссылок (ARC) , опубликованное на веб-сайте проекта Clang, чтобы лучше понять, что это было около. Я обнаружил там (и нигде больше) упоминание об использовании объявлений __attribute__, чтобы указать ARC, является ли определенный код автоматически высвобождает свое возвращаемое значение, например (__attribute__((ns_returns_autoreleased))), или «потребляет» ли он параметр (__attribute((ns_consumed))) и т. д.

Однако, похоже, что в руководстве очень мало говорится о фактическом уровне необходимости, который имеют эти заявления. Исключение из них, по-видимому, не имеет значения ни при запуске статического анализатора, ни при запуске самого проекта. Имеют ли они хоть разницу? Есть ли какое-либо преимущество в маркировке метода с помощью __attribute__((objc_method_family(new)))? Ни одна статья, которую я нашел на ARC, не упоминает эти спецификаторы вообще; возможно, гуру ARC может рассказать, для чего они используются.

(Лично я включаю все соответствующие спецификаторы на всякий случай, но считаю, что они делают код запутанным и грязным.)

Ответы [ 3 ]

5 голосов
/ 01 октября 2011

Эти атрибуты предназначены специально для ненормальных случаев, таких как:

Параметр функции или метода типа указателя сохраняемого объекта может быть помечен как использованный, что означает, что вызываемый объект ожидает получить +1 retain count.

Функция или метод, которые возвращают тип указателя сохраняемого объекта, могут быть помечены как возвращающие сохраненное значение, что означает, что вызывающая сторона ожидает вступления во владение +1 сохраняемым счетом.*

Обычно вы не делаете эти вещи, поэтому вы обычно не используете эти атрибуты.Без атрибутов нормальное поведение - правило NARC или, возможно, в рамках ARC, я бы сказал CAN - это то, что компилятор реализует и ожидает.

Есть две причины для использования этих атрибутов:

  • Для нарушения правила CAN;то есть иметь метод с не таким именем, который возвращает ссылку, или метод с таким именем, который не имеет.Атрибут документирует нарушение в прототипе метода и может даже потребоваться для его реализации, если в реализации используется ARC.
  • Работа с типами Core Foundation, включая типы Core Graphics.Это не ARCed, поэтому вам нужно использовать атрибуты моста, чтобы помочь преобразованию в и из типов «указатель сохраняемого объекта».
3 голосов
/ 01 октября 2011

В большинстве случаев это не нужно, поскольку LLVM & Clang знает соглашения об именах ObjC. Поэтому, если вы следуете стандартным соглашениям об именах Какао, LLVM автоматически предполагает соблюдение соответствующей политики семейства / возврата памяти.

А именно, если вы объявите метод с именем initWith..., он автоматически будет рассматривать его как семейство методов init, нет необходимости указывать __attribute__((objc_method_family(init))), Clang автоматически обнаружит его; то же самое для семьи new и т. д.

Фактически, вам нужно использовать спецификаторы __attribute__ только тогда, когда Clang не может угадать такие случаи, что на практике встречается редко (на практике мне никогда не приходилось это использовать), или только если вы не уважаете именование условные обозначения:


Цитирование Документация по языкам Clang :

Многие методы в Objective-C имеют общепринятые значения, определяемые их селекторами. Для целей статического анализа иногда полезно иметь возможность пометить метод как , имеющий конкретное общепринятое значение, несмотря на отсутствие правильного селектора , или не имеющий общепринятого значения, предложенного его селектором. Для этих случаев использования мы предоставляем атрибут, специально описывающий семейство методов, к которому принадлежит метод.

Так что, как только вы соблюдаете соглашения об именах (что вы всегда должны делать), вам больше нечего делать.

0 голосов
/ 14 октября 2011

Вы должны обязательно придерживаться правил именования, где это возможно.

...