NSMutableDictionary的取值与赋值

2022-11-12  本文已影响0人  今天写明天改

背景

NSMutableDictionary这个基础的数据类型在OC里大家经常使用,然而用的时候大家不知道有没有注意过,NSMutableDictionary的取值和存值是有两种不同的方式的。

NSMutableDictionary赋值

赋值一共有两个方法:

1. func setObject(_ anObject: Any, forKey aKey: NSCopying )

2. func setValue(_value:Any?,forKey key: String)

官方对他们的解释都是: 将给定的键值对添加到字典中。那么这两个方法有什么区别呢,我们看以下几个方面

参数

setObject(_ anObject: Any, forKey aKey: NSCopying)函数:

anObject: aKey的值。字典维护对对象的强引用。

aKey: 值的键。键被复制(使用copy(with:);键必须符合NSCopying协议)。如果字典中已经存在一个Key,则用anObject代替它。

setValue(_value:Any?,forKey key: String)函数:

value: 键的值。

key: 值的键。请注意,在使用键值编码时,键必须是字符串(请参见访问对象属性)。

这里有两点不同

1. setValue:forKey:中的key参数必须是一个字符串 而setObject:forKey:中的key参数可以是任何符合NSCopying协议的对象。

2. setObject:forKey:中的anObject参数是不能为nil的, 如果需要在字典中表示nil值,请使用NSNull,而 setValue:forKey:中的value参数则没有限制。

行为

还有什么不同呢?官方的注解中有一句话是:setValue:forKey:方法使用setObject:forKey:将值和键添加到字典中,除非值为零,在这种情况下,该方法会尝试使用removeObjectForKey:删除键。,也就是在值为nil的情况下,两者的行为是不同的

强调

这里要强调一点我们在上面说的setValue:forKey:方法是NSMutableDictionary的方法,是NSMutabledictionary特有的,而不是NSKeyValueCoding的主要方法setValue:forKey:,虽让他们的参数和函数名都一样。

比如:我们如果看官方文档,会发现NSKeyValueCoding中的setValue(_:forKey:)方法中的参数的含义分别是:

value: 键标识的属性的值。

key: 接收者属性之一的名称。

NSMutableDictionary取值

取值有两个方法:

1. - (ObjectType)valueForKey:(NSString  *)key;

2. - (ObjectType)objectForKey:(KeyType)aKey;

他们的作用都是: 返回与给定键关联的值。我们看一下两个方法的不同:

参数

valueForKey:方法的参数在使用键值编码时,键必须是字符串(请参见访问对象属性)

行为

两个方法返回的是与aKey关联的值,如果没有值与aKey关联,则为nil, 但是valueForKey:方法中,如果键不是以“@”开头,则调用objectForKey:。如果键以“@”开头,则去掉“@”并用键的其余部分调用[super valueForKey:]。假设我们有如下代码,那么会发生什么事情呢?

NSDictionary *dic = [NSDictionary dictionaryWithObject:@"value" forKey:@"@key"];

id value1 = [dic objectForKey:@"@key"];

id value2 = [dic valueForKey:@"@key"];

大家知道value1是什么吗? 是"value"这个字符串,这个大家容易理解,因为存的时候就是"key"这个键对应“value”这个字符串。

那么value2是什么呢?答案是"@key"这个字符串。说到这里有同学怕是要拍案而起了,因为按照kvc的理论:valueForKey:这个方法返回由key参数命名的属性的值。如果根据访问者搜索模式中描述的规则找不到由键命名的属性,则该对象会向自己发送一条valueForUndefinedKey:消息。valueForUndefinedKey:的默认实现引发NSUndefined KeyException,但子类可能会覆盖此行为并更优雅地处理此情况。

实际上,这里我们可以试试将

NSDictionary *dic = [NSDictionary dictionaryWithObject:@"value" forKey:@"@key"]; 

这个NSDictionary的key换成任何的字符串,你会发现,都会产生NSUndefined KeyException。那么为什么"@key"字符串不会呢,大家可以看看对应的NSDictionary的源码,就会发现这个奥秘了。(如果还没有懂,请来问哦)

总结:

有些东西,一定要自己多看文档,才会了解其中的精髓,只停留在大概差不多的水平的话,那就躺平了。

上一篇 下一篇

猜你喜欢

热点阅读