Objective-C: różnica między ID i void *
Jaka jest różnica między id
a void *
?
7 answers
void *
oznacza "odniesienie do jakiegoś przypadkowego fragmentu pamięci z nieopisaną / nieznaną zawartością" [21]}
id
oznacza "odniesienie do jakiegoś losowego obiektu-C nieznanej klasy"
Istnieją dodatkowe różnice semantyczne:
W trybie tylko GC lub obsługiwanym przez GC kompilator będzie emitował bariery zapisu dla referencji typu
id
, ale nie dla typuvoid *
. Podczas deklarowania struktur może to być krytyczna różnica. Deklarowanie ivarów jakvoid *_superPrivateDoNotTouch;
będzie powoduje przedwczesne zbieranie obiektów, jeśli {[7] } jest rzeczywiście obiektem. Nie rób tego.Próba wywołania metody na referencji typu
void *
spowoduje wyświetlenie ostrzeżenia kompilatora.Próba wywołania metody na typie
id
będzie ostrzegać tylko wtedy, gdy wywołana metoda nie została zadeklarowana w żadnej z deklaracji@interface
widzianych przez kompilator.
Tak więc, nigdy nie należy odnosić się do obiektu jako void *
. Podobnie należy unikać użycie zmiennej typu id
do odniesienia się do obiektu. Użyj najbardziej specyficznego odniesienia do klasy, które możesz wpisać. Nawet NSObject *
jest lepsze niż id
, ponieważ kompilator może przynajmniej zapewnić lepszą walidację wywołań metody względem tego odniesienia.
Jedynym powszechnym i prawidłowym użyciem void *
jest nieprzezroczyste odniesienie do danych, które jest przekazywane przez inne API.
Rozważmy metodę sortedArrayUsingFunction: context:
z NSArray
:
- (NSArray *)sortedArrayUsingFunction:(NSInteger (*)(id, id, void *))comparator context:(void *)context;
Funkcja sortowania zostanie zadeklarowana as:
NSInteger mySortFunc(id left, id right, void *context) { ...; }
W tym przypadku NSArray przekazuje tylko to, co przekazujesz jako argument context
do metody through jako argument context
. Jest to nieprzezroczysty kawałek danych o rozmiarze wskaźnika, jeśli chodzi o NSArray, i możesz go używać w dowolnym celu.
BEZ funkcji typu zamknięcia w języku, jest to jedyny sposób na przenoszenie kawałka danych za pomocą funkcji. Przykład; jeśli chcesz, aby funkcja mySortFunc() warunkowo sortowała wielkość liter lub niewrażliwe na wielkość liter, będąc jednocześnie bezpiecznym dla wątków, można przekazać wskaźnik is-case-sensitive w kontekście, prawdopodobnie rzucając się na drogę wejścia i wyjścia.
Kruche i podatne na błędy, ale jedyne wyjście.Bloki rozwiązują to -- bloki są zamknięciami dla C. są dostępne w Clang -- http://llvm.org / i są wszechobecne w Snow Leopardzie (http://developer.apple.com/library/ios/documentation/Performance/Reference/GCD_libdispatch_Ref/GCD_libdispatch_Ref.pdf).
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2012-11-09 10:12:45
Id jest wskaźnikiem do obiektu objective C, gdzie jako void* jest wskaźnikiem do czegokolwiek.
Id wyłącza również ostrzeżenia związane z wywołaniem nieznanych mthods, więc na przykład:
[(id)obj doSomethingWeirdYouveNeverHeardOf];
Nie da zwykłego ostrzeżenia o nieznanych metodach. Spowoduje to oczywiście wywołanie wyjątku w czasie wykonywania, chyba że obj jest zerowy lub naprawdę zaimplementuje tę metodę.
Często powinieneś użyć NSObject*
lub id<NSObject>
zamiast id
, co przynajmniej potwierdza, że zwracany obiekt jest Obiekt Cocoa, dzięki czemu można bezpiecznie używać na nim metod takich jak retain/release/autorelease.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-03-14 19:56:41
Jeśli metoda ma zwracany typ id
, możesz zwrócić dowolny obiekt Objective-C.
void
oznacza to, że metoda niczego nie zwróci.
void *
to tylko wskazówka. Nie będzie można edytować zawartości pod adresem, na który wskazuje wskaźnik.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-20 05:53:00
id
jest wskaźnikiem do obiektu Objective-C. void *
jest wskaźnikiem do czegokolwiek . Możesz użyć void *
zamiast id
, ale nie jest to zalecane, ponieważ nigdy nie otrzymasz ostrzeżeń kompilatora dla czegokolwiek.
You may want to see stackoverflow.com/questions/466777/whats-the-difference-between-declaring-a-variable-id-and-nsobject i unixjunkie.blogspot.com/2008/03/id-vs-nsobject-vs-id.html .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
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;
Powyższy kod pochodzi z objc.h, wygląda więc na to, że id jest instancją struktury objc_object, a wskaźnik isa może wiązać się z dowolnym obiektem klasy Objective C, podczas gdy void* jest tylko nietypowanym wskaźnikiem.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-01-19 09:21:52
Rozumiem, że id reprezentuje wskaźnik do obiektu, podczas gdy void * może wskazywać na cokolwiek naprawdę, o ile następnie rzucisz go na typ, do którego chcesz go użyć
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-20 05:54:09
Oprócz tego, co już zostało powiedziane, Istnieje różnica między obiektami a wskaźnikami związanymi ze zbiorami. Na przykład, jeśli chcesz umieścić coś w NSArray, potrzebujesz obiektu (typu "id") i nie możesz używać tam wskaźnika surowych danych (typu " void *"). Możesz użyć [NSValue valueWithPointer:rawData]
, Aby przekonwertować void *rawDdata
na typ "id", aby użyć go wewnątrz kolekcji. Ogólnie " id " jest bardziej elastyczny i ma więcej semantyki związanej z dołączonymi do niego obiektami. Jest więcej przykładów wyjaśniających Typ id Objective C here .
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-30 06:57:42