Jaka jest różnica między setObject: forKey: i setValue: forKey: w NSMutableDictionary?

153

Patrząc na dokumentację, nie widzę dużej różnicy. Zarówno „wartość”, jak i „obiekt” są typu id , więc może to być dowolny obiekt. Klucz jest kiedyś łańcuchem, aw innym przypadku identyfikatorem. Jeden z nich wydaje się zatrzymywać obiekt, a drugi nie. Co jeszcze? Który jest do jakiego przypadku?

EI Captain v2.0
źródło

Odpowiedzi:

163

setValue:forKey:jest częścią protokołu NSKeyValueCoding , który między innymi umożliwia dostęp do właściwości obiektów, takich jak Interface Builder. setValue:forKey:jest implementowany w klasach innych niż NSDictionary.

setObject:forKey:jest NSMutableDictionary'spowodem do istnienia. Jego sygnatura jest podobna do setValue: forKey :, ale jest bardziej ogólna (np. Dowolny typ klucza). To trochę zbieg okoliczności, że podpisy są tak podobne.

To, co dodaje do zamieszania, to fakt, że implementacja NSMutableDictionary setValue:forKey:jest równoważna setObject:forKey:w większości przypadków. W innych klasach setValue:forKey:zmienia zmienne składowe. WNSMutableDictionary zmienia wpisy w słowniku, chyba że poprzedzisz klucz znakiem „@” - w takim przypadku modyfikuje zmienne składowe.

Tak, w skrócie, użytkowania setObject:forKey:, gdy trzeba pracować z słownikowych kluczy i wartości, a setValue:forKey:w przypadkach rzadkich, gdzie trzeba walki KVP .

EDYCJA: i och, wygląda na to, że zadawano to wcześniej pytanie i odpowiadano: Różnica między objectForKey i valueForKey?

Oren Trutner
źródło
to nie jest dokładnie to samo. chodzi o metody pobierające, podczas gdy to pytanie dotyczy metod ustawiających
user102008
1
Co masz na myśli, mówiąc „W NSMutableDictionary zmienia wpisy słownika, chyba że poprzedzisz klucz znakiem„ @ ”- w takim przypadku modyfikuje zmienne składowe.” Jakie zmienne składowe? Może też możesz skomentować stackoverflow.com/questions/5755917 ? Dzięki.
Peter Štibraný
tylko dla kompletności, setObject: forKey zgłosi (wyjątek), jeśli obiekt jest zerowy. Czy setValue: forKey zachowa się tak samo, czy usunie istniejący obiekt ze słownika przy ustawieniu nil dla klucza?
Motti Shneor
Świetna odpowiedź. Naprawdę. jednak dla kompletności dobrze byłoby wspomnieć, że (przynajmniej na NSMutableDictionary) setValue: forKey: toleruje wartości zerowe i usuwa wpis - podczas gdy setObject: forKey: wyrzuci wyjątek i zawiesi się po podaniu wartości zerowej.
Motti Shneor
83

Inną różnicą jest to, że jeśli podasz wartość nil setValue:forKey:, to usuwa klucz ze słownika, jeśli istnieje, w przeciwnym razie nic nie robi. Ale jeśli podasz wartość zero setObject:forKey:, zgłosi to wyjątek.

user102008
źródło
10
Warto o tym wiedzieć. Napisałem własną kategorię w NSMutableDictionary, aby osiągnąć dokładnie to! Dzięki
Arman
2
Inna różnica polega na tym, że w przypadku indeksowania celu-c możesz napisać, dic[key] = value;aby obsługiwał usuwanie klucza, jeśli wartość jest nil. Subskrypcja jest ogólnie lepszym podejściem niż setValue:forKey:osiągnięcie tego.
Coœur
4

anObject - wartość klucza. Obiekt otrzymuje komunikat o zachowaniu, zanim zostanie dodany do NSDictionary. Ta wartość nie może być zerowa.

aKey - klucz do wartości. Klucz jest kopiowany (za pomocą copyWithZone:; klucze muszą być zgodne z NSCopyingprotokołem). Klucz nie może być zerowy.

wartość - wartość klucza.

klucz - klucz wartości. Pamiętaj, że w przypadku kodowania klucz-wartość klucz musi być ciągiem (zobacz „Podstawy kodowania klucz-wartość”).

breakfreehg
źródło
Dziękuję za podanie konkretnego powodu, dla którego setObject: forKey: zgłasza wyjątek. @breakfreehg
simbesi.com