NSMutableDictionary中的setObject:forKey:和setValue:forKey:有什么区别?

156

查看文档时,我几乎没有看到什么大的区别。“value”和“object”都是ID类型,因此可以是任何对象。键一种是字符串,另一种是ID。其中一个似乎保留了对象,而另一个则没有。还有什么区别?哪个用于哪种情况?


4个回答

167

setValue:forKey:NSKeyValueCoding协议的一部分,该协议允许您从Interface Builder等工具访问对象属性。除NSDictionary之外的类也实现了setValue:forKey:

setObject:forKey:NSMutableDictionary存在的原因,它的签名与setValue:forKey:非常相似,但更通用(例如任何键类型)。这两个函数的签名如此相似有些令人困惑。

令人困惑的是,在大多数情况下,NSMutableDictionary中的setValue:forKey:的实现与setObject:forKey:等效。在其他类中,setValue:forKey:会更改成员变量。在NSMutableDictionary中,它会更改字典条目,除非您在键前加上“@”字符--这样它就会修改成员变量。

因此,简而言之,当您需要使用字典键和值时,请使用setObject:forKey:,在较少的情况下,当您需要处理KVP时,请使用setValue:forKey:

编辑:噢,看起来这个问题之前已经被问过并回答过:Difference between objectForKey and valueForKey?


那个问题并不完全相同。它是关于getter方法,而这个问题是关于setter方法。 - user102008
1
“在NSMutableDictionary中,它会更改字典条目,除非您在键前加上'@'字符--在这种情况下,它会修改成员变量。”指的是哪些成员变量?另外,也许您可以对http://stackoverflow.com/questions/5755917/发表评论?谢谢。 - Peter Štibraný
仅供完整性,如果对象为nil,则setObject:forKey将引发(异常)。setValue:forKey会表现相同吗?还是在为键设置nil时,它会从字典中删除现有对象? - Motti Shneor
很好的答案。但为了完整起见,提到一下(至少在NSMutableDictionary上)setValue:forKey:可以容忍nil值并移除该条目,而setObject:forKey:会在传递nil值时抛出异常并崩溃。 - Motti Shneor
一般来说,我建议使用现代的Objective-C语法与NSMutableDictionary一起使用,这样可以完全避免混淆: NSMutableDictionary *myDict = [[NSMutableDictionary alloc] init]; myDict[myKey] = myValue; - tomacco

86

另一个区别在于,如果您给setValue:forKey:方法传递了nil值,则会从字典中删除该键(如果存在),否则不做任何操作。但是,如果您给setObject:forKey:方法传递了nil值,则会引发异常。


11
这非常有用,我原本想自己在NSMutableDictionary上创建一个类别来实现这一点!谢谢。 - Arman
2
另一个不同之处在于,使用Objective-C下标语法,您可以编写dic[key] = value;来支持在值为nil时删除键。与setValue:forKey:相比,下标语法通常是更好的方法来实现这一点。 - Cœur

11

-setValue:forKey: 只需向接收者发送 -setObject:forKey:,除非该值为 nil,在这种情况下发送-removeObjectForKey

非常简单。


哦,你说得对,兄弟。对不起。这里有文档:https://developer.apple.com/reference/foundation/nsmutabledictionary/1416335-setvalue?language=objc - Eddie

4

anObject — 键对应的值。在添加到NSDictionary之前,该对象会收到一个保留消息。该值不能为空。

aKey — 值对应的键。使用copyWithZone:进行复制(键必须符合NSCopying协议)。该键不能为空。

value — 键对应的值。

key — 值对应的键。请注意,在使用键值编码时,键必须是字符串(请参阅“键值编码基础知识”)。


感谢您提供了setObject:forKey:引发异常的实际原因。@breakfreehg - simbesi.com

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接