Objective-C: разница между id и void *

В чем разница между id и void * ?

    7 Solutions collect form web for “Objective-C: разница между id и void *”

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

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

    Существуют дополнительные смысловые различия:

    • В режимах GC Only или GC Supported компилятор будет выдавать барьеры записи для ссылок id типа, но не для типа void * . При объявлении структур это может быть критической разницей. Объявление iVars как void *_superPrivateDoNotTouch; приведет к преждевременному _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 в метод, в качестве аргумента context . Это непрозрачный кусок данных размера указателя, что касается NSArray, и вы можете использовать его в любых целях.

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

    Хрупкий и подверженный ошибкам, но единственный способ.

    Блоки решают это – Блоки являются закрытием для C. Они доступны в Clang – http://llvm.org/ и распространяются в Snow Leopard ( http://developer.apple.com/library/ios/documentation/Performance /Reference/GCD_libdispatch_Ref/GCD_libdispatch_Ref.pdf ).

    id – это указатель на объектный объект C, где void * является указателем на что угодно.

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

    [(id)obj doSomethingWeirdYouveNeverHeardOf];

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

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

    Если у метода есть возвращаемый тип 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 struct, а указатель isa может связываться с любым объектом Objective C Class, а void * – это просто нетипизированный указатель.

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

    В дополнение к тому, что уже сказано, есть разница между объектами и указателями, связанными с коллекциями. Например, если вы хотите что-то помещать в NSArray, вам нужен объект (типа «id»), и вы не можете использовать там указатель необработанных данных (типа «void *»). Вы можете использовать [NSValue valueWithPointer:rawData] для преобразования void *rawDdata в тип «id» для использования в коллекции. В общем случае «id» является более гибким и имеет большую семантику, связанную с прикрепленными к нему объектами. Здесь приведено несколько примеров, объясняющих здесь тип id Objective C.

    Interesting Posts

    размеры экрана всплеска андроида для дисплеев ldpi, mdpi, hdpi, xhdpi? – например: 1024X768 пикселей для ldpi

    Как сделать push-уведомление для прохода

    Лев, указавший неправильную версию JDK

    В чем разница между Windows 8 и Windows RT?

    Как сделать .lib-файл, когда есть .dll-файл и заголовочный файл

    Каковы основные цвета? RGB или CMY?

    Как получить доступ (или переключиться между) значками лотков с ярлыком в окнах?

    Вывод результатов запроса mysql с помощью GROUP BY

    Инъекция Мокито издевается над весенним бобаном

    Правила для символов строки строки C ++

    Как преобразовать шестнадцатеричную строку в строку java

    Как работает строковая подстрока в Swift

    Является ли законным вызывать метод запуска дважды в одной теме?

    Как добавить зависимость от Spring Boot Jar в другом проекте?

    Запуск такого же макроса excel в нескольких файлах excel

    Давайте будем гением компьютера.