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

153

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

EI Captain v2.0
источник

Ответы:

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:, это вызывает исключение.

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

-setValue:forKey:просто отправьте -setObject:forKey:получателю, если не указано значение nil, и в этом случае отправьте -removeObjectForKey.

Смертельно просто.

Якуб Трухларж
источник
о, ты прав, брат. Извини за это. Это задокументировано здесь: developer.apple.com/reference/foundation/nsmutabledictionary/…
Эдди
4

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

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

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

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

breakfreehg
источник
Спасибо за предоставленную фактическую причину, почему setObject: forKey: вызывает исключение. @breakfreehg
simbesi.com