Jaka jest różnica między objectForKey
i valueForKey
? Zajrzałem do obu dokumentów i wydawały mi się takie same.
źródło
Jaka jest różnica między objectForKey
i valueForKey
? Zajrzałem do obu dokumentów i wydawały mi się takie same.
objectForKey:
jest NSDictionary
metodą. An NSDictionary
jest klasą kolekcji podobną do tej NSArray
, z tą różnicą, że zamiast indeksów używa kluczy do rozróżniania elementów. Klucz to dowolny ciąg, który podajesz. Żadne dwa obiekty nie mogą mieć tego samego klucza (podobnie jak żadne dwa obiekty w jednym nie NSArray
mogą mieć tego samego indeksu).
valueForKey:
jest metodą KVC. Działa z KAŻDĄ klasą. valueForKey:
umożliwia dostęp do właściwości za pomocą ciągu znaków dla jej nazwy. Na przykład, jeśli mam Account
klasę z właściwością accountNumber
, mogę wykonać następujące czynności:
NSNumber *anAccountNumber = [NSNumber numberWithInt:12345];
Account *newAccount = [[Account alloc] init];
[newAccount setAccountNumber:anAccountNUmber];
NSNumber *anotherAccountNumber = [newAccount accountNumber];
Korzystając z KVC, mogę uzyskać dynamiczny dostęp do nieruchomości:
NSNumber *anAccountNumber = [NSNumber numberWithInt:12345];
Account *newAccount = [[Account alloc] init];
[newAccount setValue:anAccountNumber forKey:@"accountNumber"];
NSNumber *anotherAccountNumber = [newAccount valueForKey:@"accountNumber"];
Są to równoważne zestawy instrukcji.
Wiem, że myślisz: wow, ale sarkastycznie. KVC nie wygląda na tak przydatne. W rzeczywistości wygląda „wordy”. Ale jeśli chcesz zmienić rzeczy w czasie wykonywania, możesz zrobić wiele fajnych rzeczy, które są znacznie trudniejsze w innych językach (ale to jest poza zakresem twojego pytania).
Jeśli chcesz dowiedzieć się więcej o KVC, istnieje wiele samouczków, jeśli Google, szczególnie na blogu Scotta Stevensona . Możesz także sprawdzić NSKeyValueCoding Protocol Reference .
Mam nadzieję, że to pomaga.
Gdy to zrobisz
valueForKey:
, musisz nadać mu NSString, podczas gdyobjectForKey:
możesz wziąć dowolną podklasę NSObject jako klucz. Jest tak, ponieważ w przypadku kodowania klucz-wartość klucze są zawsze łańcuchami.W rzeczywistości dokumentacja stwierdza, że nawet jeśli podasz
valueForKey:
NSString, i tak będzie on wywoływał,objectForKey:
chyba że łańcuch zaczyna się od@
, w którym to przypadku wywołuje[super valueForKey:]
, co może wywoływaćvalueForUndefinedKey:
wyjątek.źródło
Oto świetny powód, aby używać
objectForKey:
wszędzie tam, gdzie to możliwe zamiastvalueForKey:
-valueForKey:
z nieznanym kluczem rzuci sięNSUnknownKeyException
powiedzenie „ta klasa nie jest zgodna z kodowaniem wartości klucza dla klucza”.źródło
Jak powiedziano,
objectForKey:
typem danych jest:(id)aKey
natomiastvalueForKey:
typ danych:(NSString *)key
.Na przykład:
Tak więc
valueForKey:
weźmie tylko wartość ciągu i jest metodą KVC, podczas gdyobjectForKey:
zabierze dowolny typ obiektu.objectForKey
Dostęp do wartości będzie uzyskiwał ten sam rodzaj obiektu.źródło
Spróbuję udzielić wyczerpującej odpowiedzi tutaj. Wiele punktów pojawia się w innych odpowiedziach, ale okazało się, że każda odpowiedź jest niepełna, a niektóre błędne.
Przede wszystkim
objectForKey:
jestNSDictionary
metodą, podczas gdyvalueForKey:
jest metodą protokołu KVC wymaganą od dowolnej klasy skarg KVC - w tym NSDictionary.Ponadto, jak @dreamlax napisał, podpowiedzi dokumentacji, która
NSDictionary
realizuje swojąvalueForKey:
metodę UŻYWAĆ jegoobjectForKey:
realizację. Innymi słowy -[NSDictionary valueForKey:]
wzywa[NSDictionary objectForKey:]
.Oznacza to, że
valueForKey:
nigdy nie może być szybsze niżobjectForKey:
(przy tym samym kluczu wejściowym), chociaż dokładne testy, które przeprowadziłem, wskazują na około 5% do 15% różnicy, w porównaniu z miliardami losowego dostępu do ogromnego NSDictionary. W normalnych sytuacjach różnica jest znikoma.Dalej: protokół KVC działa tylko z
NSString *
kluczami, dlategovalueForKey:
akceptuje tylkoNSString *
klucz (lub podklasę) jako klucz, podczas gdyNSDictionary
może pracować z innymi rodzajami obiektów jako kluczami - dzięki czemu „niższy poziom”objectForKey:
akceptuje dowolny obiekt, który można kopiować (zgodny z protokołem NSCopying) jako klucz.Wreszcie,
NSDictionary's
implementacjavalueForKey:
odbiega od standardowego zachowania zdefiniowanego w dokumentacji KVC i NIE wydaNSUnknownKeyException
klucza, którego nie może znaleźć - chyba że jest to klucz „specjalny” - taki, który zaczyna się od „@” - co zwykle oznacza „ agregacja ”klawisz funkcyjny (np@"@sum, @"@avg"
.). Zamiast tego zwróci zero, gdy klucz nie zostanie znaleziony w NSDictionary - zachowując się tak samo jakobjectForKey:
Poniżej znajduje się kod testowy do zademonstrowania i potwierdzenia moich notatek.
źródło