Objetivo-C: diferencia entre id y void *


¿Cuál es la diferencia entre id y void *?

Author: mk12, 2009-08-20

7 answers

void * significa "una referencia a algún fragmento aleatorio de memoria con contenido desconocido/sin escribir"

id significa "una referencia a algún objeto Objetivo-C aleatorio de clase desconocida"

Hay diferencias semánticas adicionales:

  • Bajo los modos GC Only o GC Supported, el compilador emitirá barreras de escritura para referencias de tipo id, pero no para el tipo void *. Al declarar estructuras, esta puede ser una diferencia crítica. Declarando iVars como void *_superPrivateDoNotTouch; causa la cosecha prematura de objetos si _superPrivateDoNotTouch es realmente un objeto. No hagas eso.

  • Intentar invocar un método sobre una referencia de tipo void * generará una advertencia del compilador.

  • Intentar invocar un método en un tipo id solo advertirá si el método al que se llama no ha sido declarado en ninguna de las declaraciones @interface vistas por el compilador.

Por lo tanto, uno nunca debe referirse a un objeto como un void *. Del mismo modo, uno debe evitar usando una variable de tipo id para referirse a un objeto. Utilice la referencia de clase más específica que pueda. Even NSObject * es mejor que id porque el compilador puede, al menos, proporcionar una mejor validación de las invocaciones de métodos contra esa referencia.

El único uso común y válido de void * es como una referencia de datos opaca que se pasa a través de alguna otra API.

Considere el método sortedArrayUsingFunction: context: de NSArray:

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

Se declararía la función de ordenación as:

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

En este caso, el NSArray simplemente pasa lo que pasa como el argumento context al método a través del argumento context. Es un trozo opaco de datos del tamaño de un puntero, en lo que respecta a NSArray, y usted es libre de usarlo para cualquier propósito que desee.

Sin una característica de tipo de cierre en el lenguaje, esta es la única manera de llevar un trozo de datos con una función. Ejemplo; si desea que mySortFunc () ordene condicionalmente como mayúsculas y minúsculas o insensible a mayúsculas y minúsculas, mientras que también sigue siendo seguro para subprocesos, pasaría el indicador is-case-sensitive en el contexto, probablemente emitiendo en el camino de entrada y salida.

Frágil y propenso al error, pero el único camino.

Los bloques resuelven esto Blocks Los bloques son cierres para C. Están disponibles en Clang { http://llvm.org / y son omnipresentes en el Leopardo de las Nieves (http://developer.apple.com/library/ios/documentation/Performance/Reference/GCD_libdispatch_Ref/GCD_libdispatch_Ref.pdf).

 233
Author: bbum,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2012-11-09 10:12:45

Id es un puntero a un objeto objective C, donde as void* es un puntero a cualquier cosa.

Id también desactiva las advertencias relacionadas con llamar a mthods desconocidos, por ejemplo:

[(id)obj doSomethingWeirdYouveNeverHeardOf];

No dará la advertencia habitual sobre métodos desconocidos. Por supuesto, generará una excepción en tiempo de ejecución a menos que obj sea nil o realmente implemente ese método.

A menudo debe usar NSObject* o id<NSObject> en preferencia a id, lo que al menos confirma que el objeto devuelto es un Objeto Cocoa, por lo que puede utilizar de forma segura métodos como retener/liberar/autorelease en él.

 19
Author: Peter N Lewis,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2011-03-14 19:56:41

Si un método tiene un tipo de retorno de id puede devolver cualquier objeto Objective-C.

void significa que el método no devuelve nada.

void * es sólo un indicador. No podrás editar el contenido de la dirección a la que apunta el puntero.

 8
Author: fphilipe,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-08-20 05:53:00

id es un puntero a un objeto Objective-C. {[1] } es un puntero a cualquier cosa . Puedes usar void * en lugar de id, pero no es recomendable porque nunca obtendrás advertencias del compilador para nada.

Puede Que desee ver stackoverflow.com/questions/466777/whats-the-difference-between-declaring-a-variable-id-and-nsobject y unixjunkie.blogspot.com/2008/03/id-vs-nsobject-vs-id.html.

 7
Author: Michael,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:25:54
/// 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;

El código anterior es de objc.h, por lo que parece que id es una instancia de la estructura objc_object y el puntero isa puede enlazarse con cualquier objeto de clase Objective C, mientras que void* es solo un puntero sin tipo.

 4
Author: jack,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2015-01-19 09:21:52

Entiendo que id representa un puntero a un objeto, mientras que void * puede apuntar a cualquier cosa realmente, siempre y cuando luego lo lance al tipo que desea usar como

 2
Author: hhafez,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2009-08-20 05:54:09

Además de lo que ya se ha dicho, hay una diferencia entre objetos y punteros relacionados con colecciones. Por ejemplo, si desea poner algo en NSArray, necesita un objeto (de tipo" id"), y no puede usar un puntero de datos sin procesar allí (de tipo "void*"). Puede usar [NSValue valueWithPointer:rawData] para convertir void *rawDdata al tipo "id" para usarlo dentro de una colección. En general, "id" es más flexible y tiene más semántica relacionada con los objetos adjuntos a él. Hay más ejemplos que explican id tipo de Objetivo C aquí.

 0
Author: battlmonstr,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-04-30 06:57:42