Objective C: различие между идентификатором и пусто *

А хороший разработчик должен знать больше, чем, как кодировать

167
задан mk12 22 July 2012 в 19:13
поделиться

5 ответов

void * означает "ссылка на некоторый случайный кусок памяти с нетипизированным / неизвестным содержимым »

id означает« ссылку на некоторый случайный объект Objective-C неизвестного класса »

Есть дополнительные семантические различия:

  • Только в GC или В режимах, поддерживаемых сборщиком мусора, компилятор создает барьеры для записи для ссылок типа id , но не для типа void * . При объявлении структур это может быть критическим отличием. Объявление iVars типа void * _superPrivateDoNotTouch; вызовет преждевременное пожатие объектов, если _superPrivateDoNotTouch на самом деле является объектом. Не делай этого.

  • попытка вызвать метод для ссылки типа void * вызовет предупреждение компилятора.

  • попытка вызвать метод для типа id выдаст предупреждение, только если вызываемый метод не был объявлен ни в одном из объявлений @interface , видимых компилятором.

Таким образом, нельзя ссылаться на объект как на void * . Точно так же следует избегать использования типизированной переменной id для ссылки на объект. Используйте наиболее конкретную ссылку, типизированную для класса, которую вы можете. Даже NSObject * лучше, чем id , потому что компилятор может, по крайней мере, обеспечить лучшую проверку вызовов методов по этой ссылке.

Единственное распространенное и допустимое использование void * - это непрозрачная ссылка на данные, которая передается через некоторый другой API.

Рассмотрим метод sortedArrayUsingFunction: context: для NSArray :

- (NSArray *)sortedArrayUsingFunction:(NSInteger (*)(id, id, void *))comparator context:(void *)context;

Функция сортировки будет объявлена ​​как:

NSInteger mySortFunc(id left, id right, void *context) { ...; }

В этом случае NSArray просто передает все, что вы передаете, как аргумент context в метод как аргумент контекста . Что касается NSArray, это непрозрачный кусок данных размером с указатель, и вы можете использовать его для любых целей.

Без функции типа закрытия в языке это единственный способ сохранить кусок данных с функцией. Пример; если вы хотите, чтобы mySortFunc () выполняла условную сортировку с учетом регистра или без учета регистра, но при этом оставалась поточно-ориентированной,

234
ответ дан 23 November 2019 в 21:00
поделиться

id - указатель на объект C, где void * - указатель на что угодно.

id также отключает предупреждения, связанные с вызовом неизвестных методов, например:

[(id) obj doSomethingWeirdYouveNeverHeardOf];

не будет выдавать обычное предупреждение о неизвестных методах. Конечно, это вызовет исключение во время выполнения, если obj не равен nil или действительно не реализует этот метод.

Часто вы должны использовать NSObject * или id в предпочтение id , что, по крайней мере, подтверждает, что возвращенный объект является объектом Какао, поэтому вы можете безопасно использовать для него такие методы, как keep / release / autorelease.

19
ответ дан 23 November 2019 в 21:00
поделиться

Если метод имеет тип возврата id вы можете вернуть любой объект Objective-C.

void означает, что метод ничего не вернет.

void * - это просто указатель. Вы не сможете редактировать содержимое адреса, на который указывает указатель.

8
ответ дан 23 November 2019 в 21:00
поделиться

id - указатель на объект Objective-C. void * - указатель на что-либо . Вы можете использовать void * вместо id , но это не рекомендуется, потому что вы никогда не получите предупреждений компилятора ни о чем.

Возможно, вы захотите увидеть stackoverflow.com / questions / 466777 / что-разница-между-объявлением-идентификатора-переменной-и-nsobject и unixjunkie.blogspot.com/2008/03/id-vs-nsobject-vs-id .html .

7
ответ дан 23 November 2019 в 21:00
поделиться

Насколько я понимаю, id представляет собой указатель на объект, а void * может указывать на что угодно, если вы затем приведете его к типу, который хотите использовать как

2
ответ дан 23 November 2019 в 21:00
поделиться
Другие вопросы по тегам:

Похожие вопросы: