字典的KVC与setObject:forKey:,你了解多少?

我们在初始化一个可变字典之后,再给其添加键值对的时候可以使用字典的setObject:forKey:方法,或者使用kvc的方式。

setObject:forKey:

将给定的键值对添加到字典中

- (void)setObject:(ObjectType)anObject forKey:(id<NSCopying>)aKey

参数讲解:

anObject:

aKey的值,对该对象的强引用由字典维护

重点: 如果anObject为nil的话,会抛出NSInvalidArgumentException异常,如果你想在字典中表示一个nil 值,可以使用 NSNull

比如:
[dict setObject:[NSNull null] forKey:@"null"];

打印:null = "<null>";

aKey:

valuekey,aKey将被复制(使用copyWithZone:方法;key必须遵守NSCopying协议),如果字典中存在了该key,将替换anObject

重点: 如果key为nil的话,会抛出NSInvalidArgumentException异常

也就是使用setObject:forKey:方法会对value强引用,会使value的引用计数加一。

    NSMutableDictionary *dict = @{}.mutableCopy;
    NSString *key = @"test";
    NSMutableArray *arr = [[NSMutableArray alloc] init];
    
    printf("after init retain count = %ld\n",CFGetRetainCount((__bridge CFTypeRef)(arr)));
    
    [dict setObject:arr forKey:key];
    
    printf("after setObject:forKey: retain count = %ld\n ",CFGetRetainCount((__bridge CFTypeRef)(arr)));

打印信息:

after init retain count = 1
after setObject:forKey: retain count = 2

字典的KVC

使用KVC的方式也可以为一个可变字典添加一个键值对,

- (void)setValue:(nullable ObjectType)value forKey:(NSString *)key;

value

可以为nil,当valuenil时,会调用字典的removeObjectForKey:方法,不为nil时,调用字典的setObject:forKey:方法来添加键值对

key:

需要注意的是,当使用kvc的时候,key必须是字符串

kvc在引用计数环境下,直接访问实例变量的话,value会被retain,

    NSMutableDictionary *dict = @{}.mutableCopy;
    NSMutableArray *arr = [[NSMutableArray alloc] init];
    
    printf("after init retain count = %ld\n",CFGetRetainCount((__bridge CFTypeRef)(arr)));
    
    [dict setObject:arr forKey:@"test"];
    
    printf("after setObject:forKey: retain count = %ld\n ",CFGetRetainCount((__bridge CFTypeRef)(arr)));
    
    // kvc 方式添加键值对
    [dict setValue:arr forKey:@"test2"];
    
    printf("after kvc retain count = %ld\n ",CFGetRetainCount((__bridge CFTypeRef)(arr)));

打印:

after init retain count = 1
after setObject:forKey: retain count = 2
after kvc retain count = 3

总结:
相同点:

  1. 两个方法的key都不能为nil,否则抛出NSInvalidArgumentException
  2. 都会对value强引用

不同点

  1. setObjec:forKey:key必须遵守NSCopying协议,KVC的key必须为字符串
  2. setObjec:forKey:value不能为空,否则会抛出NSInvalidArgumentException异常; KVC的value会nil时,会调用字典的removeObjectForKey:方法,否则,调用字典的setObject:forKey:方法添加键值对

取值

相应的,我们从字典中取值的时候,可以使用字典的objectForKey :方法,也可以使用valueForKey:方法。

这两种方法都比较简单,一般情况下,字典的valueForKey:方法也是调用objectForKey :来取值的,但这存在了一个前提:key不能以字符"@"开头

key不是以"@"开始时,调用字典的objectForKey:方法。如果以"@"开始的话,则去除掉"@"字符,并用剩余的字符调用[super valueForKey:]方法。当父类也没有找到该key时,会调用valueForUndefinedKey:方法,而valueForUndefinedKey:默认是抛出一个异常的。(只会去除开头的第一个"@",即如果key是以多个"@"字符开始的话,只会去除第一个开始的"@",剩余的"@"字符会被保留)

    NSMutableDictionary *dict = @{}.mutableCopy;
    NSMutableArray *arr = [[NSMutableArray alloc] init];
    NSString *key1 = @"@@@test";
    [dict setObject:arr forKey:key1];
    //取值
    id test2 = [dict valueForKey:key1];

控制台打印:

Terminating app due to uncaught exception 'NSUnknownKeyException', reason: '[<__NSDictionaryM 0x600000222a80> valueForUndefinedKey:]: this class is not key value coding-compliant for the key @@test.'

可以看到,我们本来是通过"@@@test"字符串作为key去取值的,但是在查找过程中去除了第一个"@"字符,用剩下的字符串"@@test"去作为key去查找的(不是把所有的"@"字符去除)。

另外,与赋值时不同,取值时keynil时并不会抛出异常。

删除

字典可以使用removeObjectForKey :方法删除某个键值对

- (void)removeObjectForKey:(KeyType)aKey;

key为nil的话, 会抛出NSInvalidArgumentException异常
当字典中不存在该key的时候,则什么都没做。

removeAllObjects
清空字典里的数据,其实是向字典中每个key以及对应的value发送release消息

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值