Цель-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 здесь.