iOS -setValue:forKey:和-setObject: forKey区别

KVC与NSMutableDictionary对比
本文对比分析了KVC提供的setValue:forKey:方法与NSMutableDictionary的setObject:forKey:方法的区别与联系,强调了在使用这些方法时需要注意的细节。

首先看一下下面的代码,请问程序是否会崩溃?如果不会,那么输出结果应该是什么?

NSMutableDictionary * dic = [@{@"name":@"小明"} mutableCopy];
[dic setObject:@"Men" forKey:@"gender"];
[dic setValue:nil forKey:@"gender"];
NSLog(@" -- %@ -- ",dic);

既然问到了输出结果,如果你不是很确定答案的话,应该可以猜出来程序是不会崩溃的。
下面就打个断点来看dic走完每一行代码后的结果:
这里写图片描述

这里写图片描述

这里写图片描述


-setValue: forKey: 是KVC(键-值编码)提供的方法,旨在通过key去修改一个obj的属性,如果是字典的话,则修改key对应的value,如果是数组或者集合,则会向每个对象发送此消息,去修改元素的key对应的property。
说到这里就不得不提一下:如果向一个对象a发送-satValue: forKey:消息,除非能确保a包含key对应的property(即key和A的某个property名字相同),否则必须实现类A或者其父类的-setValue: forUndefinedKey:方法,否则会导致crash。

/* Send -setObject:forKey: to the receiver, unless the value is nil, in which case send -removeObjectForKey:.
*/
- (void)setValue:(nullable ObjectType)value forKey:(NSString *)key;

按照其注释:给消息接受者发送-setObject:forKey: 消息,如果value为nil,则给消息接受者发送-removeObjectForKey:消息。

-setObject: forKey: 是NSMutableDictionary的对象方法,旨在通过去修改字典中key对应的value,如果key不存在,则添加此key-value对。
值得注意的是,为了使你的程序更加strong,当你调用-setObject: forKey:时,务必对object进行判空,只有当object不为nil时方可调用该方法,否则会导致程序crash。
这里写图片描述

    NSMutableDictionary * dic = [@{@"name":@"小明"} mutableCopy];
    //_gender是一个全局变量
    //当_gender为nil时,执行到此将会crash
//    [dic setObject:_gender forKey:@"gender"];
    //为避免此类crash,需要对_gender进行判空,如此就不会crash了,只是你从字典里可能得不到想要的信息,与crash相比,此举的用户体验要比crash强得太多了
    if (_gender) [dic setObject:_gender forKey:@"gender"];

总结一下吧
相同点:

  • 二者都可以对可变字典进行修改;

不同点:

  • -setValue:forKey:是KVC提供的方法,可对绝大部分对象进行操作(包括自定义对象),-setObject: forKey是NSMutableDictionary提供的方法,只能操作可变字典;
  • -setValue:forKey:当value为nil时,对于字典相当于删除key-value对,-setObject: forKey当object为nil时将直接导致程序crash,因此调用之前需要判空;
引用中提到了在严格模式下使用map的function声明时,this指向undefined。这可能导致一些问题。解决方法是将map里面的function声明修改为箭头函数,因为箭头函数没有自己的this,它会继承父级作用域的this。这样就可以避免this指向undefined的问题。 引用中提到了setValue:ForKey:是KVC的主要方法,而setObject:ForKey:是NSMutableDictionary特有的方法。两者之间有一些区别。如果你是在使用NSMutableDictionary,应该使用setObject:ForKey:来设置对象的值。而如果你是在使用KVC,应该使用setValue:ForKey:来设置对象的值。 引用中提到了在GetNav方法中使用map遍历数组,并为每个元素动态生成一列数据,并为每一列数据添加了onClick事件。但在运行过程中报错说updateRoute为undefined。根据错误信息来看,可能是updateRoute这个方法未定义。需要检查代码中是否有定义这个方法,并且确保被正确引用。 综上所述,问题的解决方法包括: 1. 将map里面的function声明修改为箭头函数,以解决严格模式下this指向undefined的问题。 2. 根据具体情况选择使用setValue:ForKey:setObject:ForKey:方法来设置对象的值。 3. 检查代码中是否正确定义了updateRoute方法,并确保正确引用。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [TypeError:Cannot read properties of undefined(reading XXX)](https://blog.youkuaiyun.com/qq_57558631/article/details/124961465)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [iOSsetValuesetObject区别详解](https://download.youkuaiyun.com/download/weixin_38701407/12786722)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论 2
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值