Pregunta

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

¿Fue útil?

Solución

void * significa "una referencia a algún trozo aleatorio o' memoria con desconocidos / contenidos sin tipo"

id significa "una referencia a algunos Objective-C objeto aleatoria de clase desconocida"

Existen diferencias semánticas adicionales:

  • En sólo GC o GC modos soportados, el compilador emitirá barreras de escritura para las referencias de tipo id, pero no para el tipo void *. Al declarar estructuras, esto puede ser una diferencia crítica. Declarando Ivars como void *_superPrivateDoNotTouch; causarán cosecha prematura de objetos si _superPrivateDoNotTouch es en realidad un objeto. No hagas eso.

  • intentar invocar un método en una referencia de tipo void * va a vomitar una advertencia del compilador.

  • intentar invocar un método en un tipo de id solamente un aviso cuando el método se llama no se ha declarado en cualquiera de las declaraciones @interface visto por el compilador.

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

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

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

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

La función de clasificación sería declarado como:

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

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

Sin Lugar del tipo de cierre en la lengua, esta es la única manera de llevar a lo largo de un trozo de datos con una función. Ejemplo; si quería mySortFunc () para condicionalmente especie como entre mayúsculas y minúsculas o mayúsculas o minúsculas, y al mismo tiempo dejar de ser seguro para subprocesos, usted pasaría el indicador está entre mayúsculas y minúsculas en el contexto, es probable fundición en el camino de entrada y salida.

frágil y propenso a errores, pero la única manera.

Bloques resuelven este - bloques son cierres para C. Están disponibles en Clang - http://llvm.org/ y son omnipresentes en Snow Leopard ( http: / /developer.apple.com/library/ios/documentation/Performance/Reference/GCD_libdispatch_Ref/GCD_libdispatch_Ref.pdf ).

Otros consejos

id es un puntero a un objeto objetivo C, donde como void * es un puntero a nada.

Identificación del también desactiva las advertencias relacionadas con llamar mthods desconocidos, así por ejemplo:

[(id)obj doSomethingWeirdYouveNeverHeardOf];

no dar la advertencia habitual acerca de los métodos desconocidos. Será, por supuesto, provoca una excepción en tiempo de ejecución a menos obj es nula o muy no aplicar ese método.

A menudo se debe utilizar NSObject* o id<NSObject> con preferencia a id, que al menos confirma que el objeto devuelto es un objeto de cacao, para que pueda utilizar con seguridad métodos como retener / liberar / autorelease en él.

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

significa void, el método no devuelve nada.

void * es sólo un puntero. Usted no será capaz de editar el contenido de la dirección de los puntos de puntero a.

id es un puntero a un objeto Objetivo-C. void * es un puntero a lo . Se podría utilizar en lugar de void * id, pero no es recomendable porque nunca se obtendría advertencias del compilador para nada.

Es posible que desee ver stackoverflow.com/ preguntas / 466777 / cuál es-la-diferencia-entre-declara-a-variable-id-y-NSObject y 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;

El código anterior es de objc.h, por lo que parece que la identificación es una instancia de puntero de estructura e ISA objc_object puede unirse con cualquier objeto Clase C Objetivo, mientras que void * es sólo un puntero sin tipo.

Mi entendimiento es que Identificación representa un puntero a un objeto mientras void * puede apuntar a cualquier cosa en realidad, todo el tiempo que a continuación, lanzas con el tipo que desea utilizar como

Además de lo que ya se dijo, hay una diferencia entre los objetos y punteros relacionados con colecciones. Por ejemplo, si quieres poner algo en NSArray, necesita un objeto (de tipo "id"), y no se puede utilizar un puntero de datos en bruto que hay (de tipo "void *"). Se puede utilizar para convertir [NSValue valueWithPointer:rawData] void *rawDdata al tipo "id" para usarlo dentro de una colección. En "id" en general es más flexible y tiene más semántica relacionados con los objetos unidos a él. Hay más ejemplos que explican Tipo de Identificación de Objective C aquí.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top