Что означает документация Apple, когда она указывает на правильное место для включения атрибутов ARC?

При наведении (без каламбура), чтобы уточнить, когда использовать __strong в объявлении переменной я наткнулся на эти строки в примечаниях к выпуску Переход к ARC:

Вы должны правильно декорировать переменные. При использовании квалификаторов в объявлении переменной объекта правильный формат:

  ClassName * qualifier variableName;

например:

  MyClass * __weak myWeakReference;    
  MyClass * __unsafe_unretained myUnsafeReference;

Другие варианты технически некорректны, но "прощены" компилятором. Чтобы понять проблему, см. http://cdecl.org/.

Я подозреваю, что это какая-то шутка со стороны Apple, но я не думаю, что понял. Это явно не имеет значения, но я хотел бы сделать это правильно. Какова важность правильного "декорирования" объявления переменной, и какой момент пытается сделать cdecl.org?

Изменить: уточнить, я хочу понять, почему именно писать

qualifier ClassName * variableName;

является "технически неверным".

1 ответ

Решение

Поэтому я думаю, что у меня есть ответ, но я не могу быть уверен, что я прав. Не стесняйтесь предоставить лучший, или комментарий /upvote, если вы думаете, что я прибил это.

CDecl - это программа на C, которую вы можете скачать с того же сайта. Он существует для решения таких проблем, как в этом вопросе.

Объявления переменных в C могут быть довольно печально известными, особенно если учесть typedef. На Unixwiz.net есть хорошее введение в это. Там вы найдете полезное введение, которое позволит вам читать даже таких монстров, как char *(*(**foo [][8])())[]; (foo is array of array of 8 pointer to pointer to function returning pointer to array of pointer to char).

Правило с этим эффективно близости. Рассмотрим простой пример

const int * foo

Это объявляет foo как указатель на константу int. Тем не мение,

int * const foo

объявит foo как постоянный указатель на int. Тонкая разница подробно обсуждается в этом вопросе. (по сути, в первом примере вы можете указать foo на другую константу int, но не можете изменить константу int через foo; во втором вы можете изменить int, на который указывает foo, но вы не можете сделать так, чтобы foo указывал на любую другое место в памяти).

С этими атрибутами ARC, синтаксис использования

__strong NSString * myString

объявил бы myView как указатель на "сильный" UIView. Это бессмысленно. Только указатели на объекты могут иметь атрибут быть сильным (или слабым или чем-то еще) в ARC. Поэтому стоит написать

NSString * __strong myString

так как это соответствует другим ключевым словам C.

Я спрашивал себя: что происходит в ARC, если вы объявляете сильный указатель объекта на слабый указатель объекта, скажем, на строку NSString, например

NSString * __weak * __strong myContrivedPointer;

но то же самое относится. Только указатель объекта может иметь эти ключевые слова. Следовательно, бессмысленно объявлять указатель на указатель "сильным".

Другие вопросы по тегам