可变字典中setValue:forKey和setObject:forKey的区别

可变字典中setValue:forKey和setObject:forKey的区别

在开发过程中,使用字典的频率也是非常高的,也经常会遇到一个类似
-[__NSPlaceholderDictionary initWithObjects:forKeys:count:]: attempt to insert nil object from objects[1]
crash,那发生这种crash的真实原因又是什么呢?在开发过程中我们调用setValue:forKeysetObject:forKey频率也是非常多,但大多数情况,后者居多。我们先来看下这两个函数有定义

@interface NSMutableDictionary<KeyType, ObjectType>(NSKeyValueCoding)

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

@end

该方法内部分调用在-setObject:forKey:方法去给字典赋值,在value为空的情况下会调用-removeObjectForKey:移除已有key的值。这样在一定程度上避免了给字典赋空值crash的情况发生


@interface NSMutableDictionary<KeyType, ObjectType> : NSDictionary<KeyType, ObjectType>

- (void)removeObjectForKey:(KeyType)aKey;
- (void)setObject:(ObjectType)anObject forKey:(KeyType <NSCopying>)aKey;
@end

在API上我们发现没有注释,但在文档中其代码注释非常详细:
- (void)setObject:(ObjectType)anObject forKey:(KeyType <NSCopying>)aKey;

  • anObject
    The value for aKey. A strong reference to the object is maintained by the dictionary.

Important
Raises an NSInvalidArgumentException if anObject is nil. If you need to represent a nil value in the dictionary, use NSNull.
当anobject为空时会抛出NSInvalidArgumentException异常,如果需要保存一个空值,可以使用NSNull实例

  • aKey

The key for value. The key is copied (using copyWithZone:; keys must conform to the NSCopying protocol). If aKey already exists in the dictionary, anObject takes its place.

Important
Raises an NSInvalidArgumentException if aKey is nil.

从上述API定义和文档注释中我们可以得出以下区别:

  • setObject:forKey:object不能为空,若为空则会抛出异常,若要展示一个空值,需要使用NSNull实例代替
  • setValue:forKey:value可以为空,若value为空,内部会调用removeObjectForKey:方法,移除该key所对应的值
    setValue:forKey:可以认为是对setObject:forKey:再次封装,对异常情况做了处理。

我们开发过程中遇到的字典的crash,多数是因为在调用setObject:forKey:时,传入的object为空导致的!在使用过程要尽可以有object做判空处理,若不想这么做,可以使用setValue:forKey:方法替代


   转载规则


《可变字典中setValue:forKey和setObject:forKey的区别》 志鹏 采用 知识共享署名 4.0 国际许可协议 进行许可。
 上一篇
SwiftBasicOperators SwiftBasicOperators
Basic OperatorsAn operator is a special symbol or phrase that you use to check, change, or combine values.Swift supports
2019-08-30 志鹏
下一篇 
UIStackView UIStackView
UIStackView
2019-08-27 志鹏
  目录