Przetłumaczenie wybranych fragmentów z developer.apple.com: http://developer.apple.com/mac/library/documentation/cocoa/conceptual/KeyValueCoding/Concepts/Overview.html#//apple_ref/doc/uid/20001838-SW1
Całość dokumentu nie jest 100% powiązana z Objective-J tylko z Objective-C
Key-value coding jest to mechanizm dostępu do właściwości obiektu w sposób niebezpośredni, używając ciągu znaków (strings) by zidentyfikować właściwość aniżeli wywołując metodę dostępową (accessor method) lub wywołując zmienną instancji (instance variables). W istocie, key-value coding definiuje wzorce i sygnatury metod, które metody dostępowe (accessor methods) będą w Twojej aplikacji implementować.
Implementując key-value coding elastyczne accessory (compliant accessors) w swojej aplikacji jest ważną praktyką projektowania. Accessory pomagają w wymuszeniu hermetyzacji danych, wyizolowaniu zarządzania pamięcią do scentralizowanego położenia i ułatwiają integracje z innymi techbologiami takimi jak key-value observing, Core Data, Coca bindings i skryptowanie (scriptability).
Metody kodowania key-value mogą, w wielu przypadkach, być wykorzystane do uproszenia kodu Twojej aplikacji. By dowiedzieć się więcej dlaczego Twoja aplikacja powinna wykorzystywać key-value coding compliant accessors, przeczytaj Model Object Implementation Guide
Dodatkowo rozszerzając istniejące zasady, key-value coding definiuje pewne unikalne terminologie dla siebie.
Key-value coding może być używany do dostępu trzech różnych typów vartości obiektów: atrybutów, relacji „do-jednego” i relacji „do-wielu”.
Terminologia tych właściwości jest powiązana do tych trzech typów wartości.
Atrybut jest właściwością obiektu, która jest prostą wartością taką jak: scalar, string lub boolen. Niezmienne obiekty takie jak NSColor i NSNumber są również rozważone jako atrybuty.
Właściwość, która określa relacje „do-jednego” jest obiektem który posiada właściwości do samego siebie (has properties of its own). Te zasadniecze właściwości mogą zostać zmienione bez mieniania obiektu samego w sobie. Dla przykładu, instancje superview NSView jest relacją „do-jednego” (to-one relationship)
Ostatecznie, właściwości które określają relację „do-wielu” (to-many relationship) składaja się z kolekcji powiązanych obiektów.
Instancja NSArray lub NSSet są powszechnie używane do przechowywania takich kolekcji. Jednakże, key-value coding pozwala Ci na używanie niestandardowych klas dla kolekcji i ciągle używanie ich tak jakby były NSArray lub NSSet poprzez zaimplementowanie accessorów key-value coding omawianych "Collection Accessor Patterns for To-Many Properties."
Klucz (key - będę używał tego nazewnictwa) jest string-iem, który identyfikuje szczególną właściwość obiektu. Zazwyczaj, key koresponduje z nazwą metody dostępowej (accessor method) lub zmienną instancji (instance variable) w odbierającym obiekcie. Key musi używać enkodowania ASCII, powinien być z małych liter, i może nie korzystać z białych znaków (whitespace)
Przykładowe nazwy kluczy: payee, openingBalance, transactions i amount.
Ścieżka kluczy (key path) jest ciągiem znaków tekstowych (string), których klucze (keys) są przedzielone kropką i są wykorzystywane do określenia sekwencji trawersowania (~przesuwania) po właściwościach obiektów.
Właściwość (property) pierwszego klucza (key) w kolejności jest powiązana z odbiorcą (reciver) i każdy kolejny klucz jest ewaluowany względnie do wartości poprzedniej właściwości (wiem trszeczke zawiłe.. ale w jest to prawie jak łańcuch wywołań)
Dla przykładu, ścieżka kluczy address.street będzie zwracać wartość właściwości address z obiektu odbiorcy (czyli zmienna address zwraca obiekt) a następnie determinuje właściwość street względem obiektu address (do pobrania, ustawienia wartości… zależy czy jest to setter czy getter… rozwinięcie dalej)
Metoda valueForKey: pobiera wartość określonego klucza względem odbiorcy. Jeżeli nie istnieje accessor lub zmienna instancji dla określonego klucza, wtedy odbiorca wysyła wiadomość valueForUndefinedKey:. Podstawowa implementacja valueForUndefinedKey: podnosi wyjątek NSUndefinedKeyException, jednakże podklasa może nadpisać|zastąpić (override) to zachowanie.
Podobnie, valueForKeyPath: zwraca wartość określonej ścieżki kluczy (key path), względem odbiorcy. Każdy obiekt, który w kolejności ścieżki kluczy (key path) nie podlega key-value coding dla określonego klucza otrzymuje wiadomość valueForUndefinedKey:
Metoda dictionaryWithValuesForKeys: pobiera wartości dla przekazanej tablicy kluczy względem odbiorcy. Pobrany obiekt NSDictionary zawiera wartości dla wszystkich kluczy w tablicy.
Notatka: Kolekcja obiektów takich jak NSArray, NSSet i NSDictionary nie może posiadać wartości nil. Zamiast tego wartość nil jest reprezentowana przez obiekt NSNull. NSNull zapewnia pojedynczą instancję, która reprezentuje wartość nil. Podstawowa implementacja dictionaryWithValuesForKeys: i setValuesForKeysWithDictionary: tłumaczy automatycznie NSNull i nil więc nie musisz specjalnie testować swoich obiektów dla wartości NSNull.
Kiedy wartość jest pobrana dla ścieżki kluczy (key path) dla klucza właściwości „do-wielu” (to-many property) i ten klucz nie jest ostatnim kluczem w ścieżce, zwrócona wartości jest kolekcją zawierającą wszystkie wartości kluczy po prawej stronie klucza „do wielu”. Dla przykładu, żądanie wartości o ścieżce transactions.payee pobierze tablicę zawierającą wszystkie obiekty payee, dla wszystkich transakcji. To również działa dla wieloskładnikowych tablic w ścieżce. Ścieżka kluczy accounts.transactions.payee pobierze tablicę wszystkich obiektów payee dla wszystkich transakcji, w wszystkich accounts.
Metoda setValue:forKey: ustawia wartość dla określonego klucza, względem odbiorcy, do dostarczonej wartości. Podstawowa imple,mentacja setValue:forKey: automatycznie rozpakowuje (unwraps) obiket NSValue, który reprezentuje scalars, structs i przywiązuje je do właściwości preprety. Zobacz "Scalar and Structure Support" dla szczegółowe informacje.
Jeżeli określony klucz nie istnieje, odbiorca wysyła wiadomośc setValue:fotUndefinedKey:. Podstawowa implementacja setValue:forUndefinedKey: podnosi wyjątek NSUndefinedKeyException, jednakże, podklasa może nadpisać|zamienić tą metodę do przechwycenia żądania w niestandardowych zachowaniach.
Metoda setValue:forKeyPath: zachowuje się w podobnym stylu, jednak że jest możliwe uchwycenie ścieżki kluczy (key path) tak jak pojedynczego klucza.
Ostatecznie, setValuesForKeysWithDictionary: ustawia właściwości odbiorcy wartościami z określonego słownika, używając kluczysłownika do identyfikowania właściwości (properties). Podstawowa implementacja wywołuje setValue:forKey: dla każdej pary key-value, zastępując nil obiektem NSNull jeżeli wymagane.
Jest jeszcze jeden dodatkowy przypadek, który powinieneś rozważyć; co się stanie jeśli wykonywana jest próba ustawienia nieobiektowej właściwości (non-object property) do wartości nil. W tym wypadku, odbiorca wysyła wiadomość setNilValueForKey:. Podstawowa implementacja setNilValueForKey: podnosi wyjątek NSInvalidArgumentException. Twoja aplikacja może nadpisać tą metodę zastępując domyślną wartość lub zaznaczoną wartość (marker value), i wywołać setValue:forKey: z nową wartością.
Objective-C 2.0’s dot syntax i key-value coding są prostopadłymi technologiami (orthogonal technologies). Możesz używać key-value coding bez względu czy używasz dot syntax czy nie i możesz uzywać dot syntax bez względu czy używasz KVC czy nie. Aczkolwiek, używaj „dot syntax”. W przypadku key-value coding składnia ”.” jest używana do dzielenia elementów w ścieżce kluczy key path. Jest to ważne do zapamiętania, bo kiedy chcesz uzyskać dostęp do właściwości używając „dot synatax” wywołujesz standardową metodę dostępu (accessor) u odbiorcy.
Metodę key-value coding możesz wykorzystać również do dostępu do właściwości, dla przykładu, poniżej zdefiniowana klasa:
@interface MyClass @property NSString *stringProperty; @property NSInteger integerProperty; @property MyClass *linkedInstance; @end
masz dostęp do właściwości w instancji używając KVC:
MyClass *myInstance = [[MyClass alloc] init]; NSString *string = [myInstance valueForKey:@"stringProperty"]; [myInstance setValue:[NSNumber numberWithInt:2] forKey:@"integerProperty"];
By zobrazować różnice pomiędzy właściwościami dot synatax i KVC key paths, rozważ następujący przykład:
MyClass *anotherInstance = [[MyClass alloc] init]; myInstance.linkedInstance = anotherInstance; myInstance.linkedInstance.integerProperty = 2;
Daje to ten sam rezultat jak:
MyClass *anotherInstance = [[MyClass alloc] init]; myInstance.linkedInstance = anotherInstance; [myInstance setValue:[NSNumber numberWithInt:2] forKeyPath:@"linkedInstance.integerProperty"];
Możesz używać metod key-value coding w swoim kodzie do generalizacji implementascji. Dla przykładu oba obiekty NSTableView i NSOutlineView są powiązane identyfikatorem tekstowym (string) z każda z kolumn. Tworząc identyfikator kolumny jako identyczną właściwość obiektu (property), którą chcesz wyświetlić, możesz znacząco uprościć swój kod.
Przykład 1 pokazuje implementację NSTableView delegujące metody bez uzycia key-value coding. Przykłąd 2 pokazuje korzyści z zastosowania key-value coding do pobierania wartości konkretnej kolumny używając identyfikatora jako klucza właściwość obiektu
Przykład 1: Implementacja źródłą danych bez zastosowania metody key-value coding
- (id)tableView:(NSTableView *)tableview objectValueForTableColumn:(id)column row:(int)row { ChildObject *child = [childrenArray objectAtIndex:row]; if ( [[column identifier] isEqualToString:@"name"] ) { return [child name]; } if ( [[column identifier] isEqualToString:@"age"] ) { return [child age]; } if ( [[column identifier] isEqualToString:@"favoriteColor"] ) { // etc... } // etc... }
Przykład 2: Implementacja źródła danych z wykorzystaniem metody key-value coding
- (id)tableView:(NSTableView *)tableview objectValueForTableColumn:(id)column row:(int)row { ChildObject *child = [childrenArray objectAtIndex:row]; return [child valueForKey:[column identifier]]; }