Domanda

Qual è la differenza tra id e void *?

È stato utile?

Soluzione

void * significa "un riferimento a qualche pezzo casuale o' memoria con / contenuti sconosciuti senza tipo"

id significa "un riferimento a un oggetto Objective-C casuale di classe sconosciuta"

Ci sono ulteriori differenze semantiche:

  • Sotto GC Solo o modalità GC supportati, il compilatore emetterà barriere di scrittura per i riferimenti di tipo id, ma non per il tipo void *. Quando si dichiara strutture, questa può essere una differenza critica. ivars dichiarano come void *_superPrivateDoNotTouch; causeranno mietitura prematura degli oggetti se _superPrivateDoNotTouch è in realtà un oggetto. Non farlo.

  • tentativo di invocare un metodo su un riferimento di tipo void * sarà barf un avviso del compilatore.

  • tentativo di invocare un metodo su un tipo di id avvertirà solo se il metodo di essere chiamato non è stato dichiarato in nessuna delle dichiarazioni @interface visti dal compilatore.

In questo modo, non si dovrebbe mai fare riferimento a un oggetto come void *. Analogamente, si dovrebbe evitare di utilizzare una variabile id tipizzato per fare riferimento a un oggetto. Utilizzare il più specifico riferimento digitato classe che si può. Ancora NSObject * è meglio che id perché il compilatore può, almeno, fornire una migliore convalida dei metodi invocazioni contro quel riferimento.

L'unico uso comune e valido void * è come riferimento dati opaco che viene fatto passare attraverso un altro API.

Si consideri il metodo sortedArrayUsingFunction: context: di NSArray:

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

La funzione di ordinamento sarebbe stata dichiarata come:

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

In questo caso, il NSArray semplicemente passa tutto ciò si passa come argomento context al metodo attraverso come argomento context. Si tratta di un pezzo opaca dei dati di dimensioni puntatore, per quanto NSArray è interessato, e si è liberi di usarlo per qualsiasi scopo che si desidera.

Senza Funzione chiusure nella lingua, questo è l'unico modo per portare con sé un pezzo di dati con una funzione. Esempio; se si voleva mySortFunc () per condizionalmente sorta come maiuscole e minuscole o maiuscole e minuscole, mentre però ancora in fase di thread-safe, si dovrebbe passare l'indicatore sensibile è minuscole nel contesto, probabilmente colata sul modo in e via d'uscita.

Fragile e soggetto a errori, ma l'unico modo.

Blocchi risolvono questo - I blocchi sono chiusure per C. Sono disponibili in Clang - http://llvm.org/ e sono molto diffusi in Snow Leopard ( http: / /developer.apple.com/library/ios/documentation/Performance/Reference/GCD_libdispatch_Ref/GCD_libdispatch_Ref.pdf ).

Altri suggerimenti

id è un puntatore ad un oggetto C oggettiva, dove, come void * è un puntatore a nulla.

id si spegne anche avvisi relativi a chiamare mthods sconosciuti, così per esempio:

[(id)obj doSomethingWeirdYouveNeverHeardOf];

non darà il solito avvertimento sui metodi sconosciuti. Sarà, naturalmente, solleva un'eccezione in fase di esecuzione, a meno obj è nullo o realmente non attuare tale metodo.

Spesso si consiglia di utilizzare NSObject* o id<NSObject> a preferenza di id, che almeno conferma che l'oggetto restituito è un oggetto di cacao, in modo da poter tranquillamente utilizzare metodi come mantenere / release / autorelease su di esso.

Se un metodo ha un tipo di ritorno di id è possibile restituire qualsiasi oggetto Objective-C.

void significa, il metodo non restituisce nulla.

void * è solo un puntatore. Non sarà in grado di modificare il contenuto sull'indirizzo il puntatore punta a.

id è un puntatore ad un oggetto Objective-C. void * è un puntatore a niente . Si potrebbe utilizzare void * invece di id, ma non è consigliabile perché si sarebbe mai ottenere gli avvisi del compilatore per qualsiasi cosa.

Si consiglia di vedere stackoverflow.com/ domande / 466.777 / cosa-la-differenza-tra-dichiarazione-a-variabile id-e-NSObject e 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;

Il codice di cui sopra è da objc.h, così sembra che id è un esempio di objc_object puntatore struct e ISA può legarsi con qualsiasi oggetto Objective C Class, mentre void * è solo un puntatore non tipizzato.

La mia comprensione è che id rappresenta un puntatore ad un oggetto mentre void * può puntare a qualcosa di veramente, fino a quando si poi gettato al tipo che si desidera utilizzare come

In aggiunta a ciò che è già detto, c'è una differenza tra oggetti e puntatori relativi alle collezioni. Ad esempio, se si vuole mettere qualcosa in NSArray, è necessario un oggetto (di tipo "id"), e non è possibile utilizzare un puntatore dati grezzi lì (di tipo "void *"). È possibile utilizzare per convertire [NSValue valueWithPointer:rawData] void *rawDdata al tipo di "id" per il suo utilizzo all'interno di una collezione. In generale "id" è più flessibile e ha più semantica relativi agli oggetti collegati ad esso. Ci sono altri esempi che spiegano tipo id di Objective C qui .

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top