Где разница между setObject: forKey: и setValue: forKey: в NSMutableDictionary?


153

Глядя на документацию, я почти не вижу большой разницы. И «значение», и «объект» имеют тип id , поэтому может быть любым объектом. Ключ один раз является строкой, а в другом случае - идентификатором. Один из них, кажется, сохраняет объект, а другой нет. Что еще? Какой для какого случая?


Ответы:


163

setValue:forKey:является частью протокола NSKeyValueCoding , который, помимо прочего, позволяет вам получать доступ к свойствам объекта, например, Interface Builder. setValue:forKey:реализуется в других классах, чем NSDictionary.

setObject:forKey:это NSMutableDictionary'sпричина для существования. Его сигнатура очень похожа на setValue: forKey :, но является более общей (например, любой тип ключа). Это отчасти совпадение, что подписи так похожи.

Что добавляет путаницу, так это то, что реализация NSMutableDictionary setValue:forKey:эквивалентна setObject:forKey:в большинстве случаев. В других классах setValue:forKey:изменяются переменные-члены. In NSMutableDictionary, он изменяет записи в словаре, если только вы не ставите перед ключом символ «@» - в этом случае он изменяет переменные-члены.

Итак, в двух словах, используйте, setObject:forKey:когда вам нужно работать со словарными ключами и значениями, и setValue:forKey:в более редких случаях, когда вам нужно заняться KVP .

РЕДАКТИРОВАТЬ: и о, похоже, это уже спрашивали и отвечали раньше: Разница между objectForKey и valueForKey?


этот вопрос не совсем то же самое. речь идет о методах получения, тогда как этот вопрос о методах установки
user102008

1
Что вы подразумеваете под «В NSMutableDictionary он изменяет записи словаря, если только вы не префиксируете ключ символом« @ »- в этом случае он изменяет переменные-члены». Какие переменные-члены? Также, возможно, вы можете прокомментировать stackoverflow.com/questions/5755917 ? Спасибо.
Питер Штибраны

просто для полноты setObject: forKey повысит (исключение), если объект равен нулю. Будет ли setValue: forKey вести себя так же, или он удалит существующий объект из словаря при установке nil для ключа?
Мотти Шнеор

Отличный ответ. В самом деле. хотя для полноты картины было бы неплохо упомянуть, что (по крайней мере, для NSMutableDictionary) setValue: forKey: допускает значения nil и удаляет запись - в то время как setObject: forKey: будет выдавать исключение и аварийно завершать работу при передаче значений nil.
Мотти Шнеор

83

Другое отличие состоит в том, что если вы передаете значение nil setValue:forKey:, он удаляет ключ из словаря, если он существует, в противном случае ничего не делает. Но если вы даете ноль значение setObject:forKey:, это вызывает исключение.


10
Это супер полезно знать. В противном случае я написал свою собственную категорию на NSMutableDictionary для достижения именно этого !. Спасибо
Арман

2
Другое отличие состоит в том, что с подпиской target-c вы можете написать, dic[key] = value;чтобы поддержать удаление ключа, если значение равно nil. Подписка, как правило, лучший подход, чем setValue:forKey:сделать это.
Cœur


4

anObject - значение для ключа. Объект получает сообщение сохранения перед добавлением вNSDictionary . Это значение не должно быть ноль.

aKey - Ключ для значения. Ключ копируется (используется copyWithZone:; ключи должны соответствовать NSCopyingпротоколу). Ключ не должен быть нулевым.

значение - значение для ключа.

ключ - ключ для значения. Обратите внимание, что при использовании кодирования значения ключа ключ должен быть строкой (см. «Основы кодирования значения ключа»).


Спасибо за предоставленную фактическую причину, почему setObject: forKey: вызывает исключение. @breakfreehg
simbesi.com
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.