我們在初始化一個可變字典之後,再給其添加鍵值對的時候可以使用字典的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:
value
的key
,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
,當value
爲nil
時,會調用字典的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
總結:
相同點:
- 兩個方法的
key
都不能爲nil,否則拋出NSInvalidArgumentException
- 都會對
value
強引用
不同點
setObjec:forKey:
的key
必須遵守NSCopying
協議,KVC的key
必須爲字符串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
去查找的(不是把所有的"@"
字符去除)。
另外,與賦值時不同,取值時key
爲nil
時並不會拋出異常。
刪除
字典可以使用removeObjectForKey :
方法刪除某個鍵值對
- (void)removeObjectForKey:(KeyType)aKey;
key爲nil的話, 會拋出
NSInvalidArgumentException
異常
當字典中不存在該key的時候,則什麼都沒做。
removeAllObjects
清空字典裏的數據,其實是向字典中每個key以及對應的value
發送release
消息