Цель-C: разница между id и void *
в чем разница между id
и void *
?
7 ответов:
void *
означает "ссылка на некоторый случайный кусок памяти с нетипизированным / неизвестным содержимым"
id
означает "ссылка на некоторый случайный объект Objective-C неизвестного класса"есть дополнительные семантические различия:
в соответствии с ГК или ГК поддерживаемые режимы, компилятор выдаст писать барьеры для ссылки типа
id
, но не для типаvoid *
. При объявлении структур это может быть критическим различием. Объявляя ивары как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
аргумент к методу через Как
id-это указатель на объект objective C, где as void* - указатель на что-либо.
id также отключает предупреждения, связанные с вызовом неизвестных mthods, например:
[(id)obj doSomethingWeirdYouveNeverHeardOf];
не будет давать обычное предупреждение о неизвестных методах. Это, конечно, вызовет исключение во время выполнения, если obj не равен нулю или действительно не реализует этот метод.
часто вы должны использовать
NSObject*
илиid<NSObject>
вместоid
, который по крайней мере подтверждает, что возвращаемый объект является объектом Cocoa, поэтому вы можете безопасно использовать такие методы, как retain/release/autorelease на нем.
Если метод имеет тип возвращаемого
id
вы можете вернуть любой объект Objective-C.
void
означает, что метод ничего не вернет.
void *
- это просто указатель. Вы не сможете редактировать содержимое по адресу, на который указывает указатель.
id
- указатель на объект Objective-C.void *
указатель что-нибудь. Вы могли бы использоватьvoid *
вместоid
, но это не рекомендуется, потому что вы никогда не получите предупреждения компилятора ничего.вы можете увидеть stackoverflow.com/questions/466777/whats-the-difference-between-declaring-a-variable-id-and-nsobject и unixjunkie.blogspot.com/2008/03/id-vs-nsobject-vs-id.html.
/// Represents an instance of a class. struct objc_object { Class isa OBJC_ISA_AVAILABILITY; }; /// A pointer to an instance of a class. typedef struct objc_object *id;
приведенный выше код от objc.h, поэтому похоже, что id является экземпляром структуры objc_object, а указатель isa может связываться с любым объектом класса Objective C, в то время как void* - это просто нетипизированный указатель.
Я понимаю, что id представляет собой указатель на объект, а void * может указывать на что-либо действительно, если вы затем приведете его к типу, который вы хотите использовать как
в дополнение к тому, что уже сказано, есть разница между объектами и указателями, связанными с коллекциями. Например, если вы хотите поместить что-то в NSArray, вам нужен объект (типа "id"), и вы не можете использовать указатель необработанных данных там (типа "void *"). Вы можете использовать
[NSValue valueWithPointer:rawData]
преобразованиеvoid *rawDdata
к типу " id " для использования его внутри коллекции. В целом "id" является более гибким и имеет больше семантики, связанной с объектами, прикрепленными к нему. Есть еще примеры, объясняющие id тип цели C здесь.