W Objective-C, jaka jest różnica między deklarowaniem zmiennej id
a deklarowaniem jej jako NSObject *
?Jaka jest różnica między deklarowaniem zmiennej "id" i "NSObject *"?
Odpowiedz
Ze zmienną wpisaną na id
można wysłać jej wiadomość, a kompilator nie złoży reklamacji. Ze zmienną typu NSObject *
można wysyłać tylko komunikaty zadeklarowane przez NSObject (nie metody jakiejkolwiek podklasy), ponieważ spowoduje to wygenerowanie ostrzeżenia. Ogólnie rzecz biorąc, chcesz uzyskać id
.
Dalsze wyjaśnienie: Wszystkie obiekty są zasadniczo typu id
. Punktem deklarowania typu statycznego jest przekazanie kompilatorowi: "Załóżmy, że ten obiekt jest członkiem tej klasy." Więc jeśli wyślesz mu wiadomość, której klasa nie deklaruje, kompilator może powiedzieć: "Czekaj, ten obiekt nie powinien dostać tej wiadomości!" Ponadto, jeśli dwie klasy mają metody o tej samej nazwie, ale o różnych sygnaturach (to jest typach argumentów lub zwracanych), można je zgadnąć, którą metodę oznacza klasa, którą zadeklarowałeś dla zmiennej. Jeśli zostanie zadeklarowany jako id
, kompilator po prostu podniesie ręce i powie: "OK, nie mam wystarczających informacji tutaj." Wybieram podpis metody losowo. " (To generalnie nie będzie pomagał deklarując NSObject*
, choć. Zwykle jest konflikt między dwoma bardziej konkretnych klas.)
Świetne wyjaśnienie, choć wahałem się powiedzieć, że "Ogólnie rzecz biorąc, id jest tym, czego chcesz". Chociaż "id" jest dość elastyczny ze względu na dynamiczne pisanie, nie zapewnia praktycznie żadnych ostrzeżeń, więc jeśli wywołasz nieobsługiwaną metodę, to, co może zostać przechwycone podczas kompilacji, staje się problemem w czasie wykonywania. Pisanie statyczne (za pomocą MyClassName * itp.), gdy jest używane rozważnie, może znacznie uprościć życie, szczególnie podczas debugowania w Xcode (może pokazać bardziej inteligentne podsumowanie obiektu) lub wywołania metody catch z błędnie lub niekompletnymi selektorami. –
Rozróżnienie, które zamierzałem narysować, to między konkretnie id i NSObject *, a nie ogólnie typowanie statyczne. Znacznie częściej używamy identyfikatora niż statycznego typu jako NSObject. – Chuck
@simpleBob: Stąd "jakakolwiek znana wiadomość". – Chuck
id
oznacza „obiekt”, NSObject *
oznacza „instancję NSObject
lub jednej z jej podklas”. Istnieją obiekty w Objective-C, które nie są NSObject
s (te, które spotkasz w Cocoa w tej chwili są NSProxy
,i Class
). Jeśli jakiś kod oczekuje obiektu danej klasy, deklarując, że pomaga kompilatorowi sprawdzić, czy używasz go poprawnie. Jeśli naprawdę możesz wziąć "dowolny obiekt" - na przykład deklarujesz delegata i przetestujesz wszystkie metody wysyłania z rozmowami respondsToSelector:
- możesz użyć numeru .
Innym sposobem zadeklarować zmienną przedmiot jest jak „id <NSObject>
”, co oznacza „każdy obiekt, który realizuje NSObject
protokół.
NSProxy i Protocol to klasy. "Klasa" nie jest klasą, ale po prostu typem, który może odnosić się do wskaźników do obiektów klasy. Nie grupuj ich razem. – user102008
@ user102008: możesz wysyłać wiadomości do klasy, co czyni je obiektem w świecie objc. –
tak, obiekty klasy są obiektami, ale nie należą do klasy o nazwie "Klasa" – user102008
Z moją ograniczoną zrozumienia celu C nie wszystkie obiekty pochodzą z NSObject (w przeciwieństwie Java, gdzie wszystkie obiekty pochodzą z Object) Teoretycznie możesz mieć inne obiekty root ID może mieć zastosowanie do dowolnych obiektów pochodnych nie pochodzących z NSObject
Chciałbym dodać kolejną różnicę. Gdy dodajesz protokół do id
, nie oznacza to już, że będzie to typ NSObject *
, to po prostu oznacza, że będzie to jakikolwiek clas s to potwierdza ten protokół.
Tak więc, na przykład, ten kod nie będzie rzucać żadnego błędu, ponieważ NSObject
„s kategoria NSDelayedPerforming
ma tę metodę:
id testId;
[testId performSelector:@selector(isKindOfClass:) withObject:[NSObject class] afterDelay:.5];
Jednak ten kod pokaże błąd No known instance method for selector "performSelector:withObject:afterDelay:"
:
id<NSMutableCopying> testId;
[testId performSelector:@selector(isKindOfClass:) withObject:[NSObject class] afterDelay:.5];
- 1. Jaka jest różnica między identyfikatorem @id i @ +?
- 2. jaka jest różnica między deklarowaniem zmiennej z metody głównej a metodą główną?
- 3. Jaka jest różnica między? : i ||
- 4. Jaka jest różnica między $ i $$?
- 5. Jaka jest różnica między wstawianiem @Aemowired do zmiennej i metody?
- 6. Jaka jest różnica między = i => dla zmiennej?
- 7. Jaka jest różnica między NaN i None?
- 8. Jaka jest różnica między NetFx45WebLink i NetFx45RedistLink
- 9. Jaka jest różnica między getSupportFragmentManager() i getChildFragmentManager()?
- 10. Jaka jest różnica między "krótkim int" i "short" wc?
- 11. Różnica między $ ("# id"). Load i $ .ajax?
- 12. Jaka jest różnica między Subtotal i BaseSubtotal?
- 13. Jaka jest różnica między DetachedCriteria i ICriteria
- 14. Jaka jest różnica między & # x00A0; i ?
- 15. Jaka jest różnica między lex i yacc
- 16. jaka jest różnica między dijit i dojo
- 17. Jaka jest różnica między Control.Select() i Control.Focus()?
- 18. Jaka jest różnica między System.Windows.Controls.Control i System.Windows.Forms.Control?
- 19. Jaka jest różnica między apletami i SWING?
- 20. Jaka jest różnica między session.commit() i session.flush()?
- 21. Jaka jest różnica między ImageView.setBackgroundResource i ImageView.setImageResource?
- 22. Jaka jest różnica między Konwertuj i parsuj?
- 23. Jaka jest różnica między JSP i JSTL?
- 24. Jaka jest różnica między Lazarus i CodeTyphon
- 25. Jaka jest różnica między crc32 i crc32b?
- 26. Jaka jest różnica między TypedArray.getInteger() i TypedArray.getInt()?
- 27. jaka jest różnica między ARM7 i ARM7s
- 28. Jaka jest różnica między http_build_str() i http_build_query()?
- 29. Jaka jest różnica między "CompletionStage" i "CompletableFuture"?
- 30. Jaka jest różnica między mock.patch.object (... i mock.patch (
NSObject zawiera isa wskaźnik, id nie. Spójrz na http://stackoverflow.com/a/19634973/944634 –