第一部分 collection包含的基础对象内存管理语义
NSMutableDictionary key、value内存管理语义
NSMutableString *key = [NSMutableString stringWithFormat:@"%@",@"keykey222"];
NSMutableString *value = [NSMutableString stringWithFormat:@"%@",@"value111"];
NSLog(@"%p,%p",key,value);
NSMutableDictionary *muDic = [NSMutableDictionary dictionary];
[muDic setObject:value forKey:key];
NSLog(@"%p,%p",[muDic allKeys][0],[muDic allValues][0]);
输出结果中可以看到,muDic中的value地址同初始化的value是同一个地址,可以证明此时值的语义是“retain”,而键的地址发生了较大的变化,可以肯定的是键是发生了copy操作,而且操作系统在此处更是进行了优化,muDic里面键的类型优化为 NSTaggedPointerString
类型
上述是在键为可变类型时的结果,再看键为不可变类型的情况:
NSString *key = [NSString stringWithFormat:@"%@",@"keykey222"];
NSString *value = [NSString stringWithFormat:@"%@",@"value111"];
NSLog(@"%p,%p",key,value);
NSMutableDictionary *muDic = [NSMutableDictionary dictionary];
[muDic setObject:value forKey:key];
NSLog(@"%p,%p",[muDic allKeys][0],[muDic allValues][0]);
输出结果中键、值的地址均未发生改变,此时键、值均是“retain”操作
值得注意的是如果muDic初始化方法修改为
NSMutableDictionary *muDic = [NSMutableDictionary dictionaryWithObjectsAndKeys:value,key, nil];
实验结果也是一样的,另外NSDictionary
的实验结果同上述完全一致。
NSMutableArray里面对象的内存管理语义
NSMutableArray *muArray = [NSMutableArray array];
NSMutableString *object = [NSMutableString stringWithFormat:@"%@",@"object_1"];
NSLog(@"%p",object);
[muArray addObject:object];
NSLog(@"%p",[muArray objectAtIndex:0]);
实验结果:
2019-09-24 09:56:03.392890+0800 ARCMemory[91538:9726448] 0x600000656370
2019-09-24 09:56:03.393089+0800 ARCMemory[91538:9726448] 0x600000656370
地址完全一样,说明array对里面的对象是一个“retain”操作,添加的对象类型为不可变NSString
,结果是一样的。
另外,NSArray
的实验结果同上述一致,apple这样做也合乎情理,无法保证添加到array里面的对象都可以进行copy操作。
当然,如果有特殊需求,可以使用“toll-free bridging”技术重新定义collection对象里的内存管理语义
第二部分 collection 发生copy、mutableCopy时的内存管理语义
NSDictionary 进行copy操作
NSString *key = [NSString stringWithFormat:@"%@",@"keykey222"];
NSString *value = [NSString stringWithFormat:@"%@",@"value111"];
NSLog(@"原始的key、value地址__%p,%p",key,value);
NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:value,key, nil];
NSLog(@"dic中key、value的地址__%p,%p",[dic allKeys][0],[dic allValues][0]);
NSLog(@"dic的地址__%p",dic);
NSDictionary *copyDic = [dic copy];
NSLog(@"copyDic的地址__%p",copyDic);
NSLog(@"copyDic中key、value的地址__%p,%p",[dic allKeys][0],[dic allValues][0]);
打印结果:
2019-09-26 20:12:52.311244+0800 ARCMemory[14154:11058565] 原始的key、value地址__0xbd1d66bd8b110c11,0xbc358bfc8267d770
2019-09-26 20:12:52.311429+0800 ARCMemory[14154:11058565] dic中key、value的地址__0xbd1d66bd8b110c11,0xbc358bfc8267d770
2019-09-26 20:12:52.311575+0800 ARCMemory[14154:11058565] dic的地址__0x600001a638c0
2019-09-26 20:12:52.311672+0800 ARCMemory[14154:11058565] copyDic的地址__0x600001a638c0
2019-09-26 20:12:52.311763+0800 ARCMemory[14154:11058565] copyDic中key、value的地址__0xbd1d66bd8b110c11,0xbc358bfc8267d770
打印结果显示所有对应的地址都是一样的,在新的copyDic里,不仅copyDic是一个retain操作,就连copyDic里面的key、value都是retain操作。
NSDictionary mutableCopy
NSString *key = [NSString stringWithFormat:@"%@",@"keykey222"];
NSString *value = [NSString stringWithFormat:@"%@",@"value111"];
NSLog(@"原始的key、value地址__%p,%p",key,value);
NSDictionary *dic = [NSDictionary dictionaryWithObjectsAndKeys:value,key, nil];
NSLog(@"dic中key、value的地址__%p,%p",[dic allKeys][0],[dic allValues][0]);
NSLog(@"dic的地址__%p",dic);
NSDictionary *copyDic = [dic mutableCopy];
NSLog(@"copyDic的地址__%p",copyDic);
NSLog(@"copyDic中key、value的地址__%p,%p",[dic allKeys][0],[dic allValues][0]);
//打印结果
2019-09-26 20:21:34.293148+0800 ARCMemory[14403:11067674] 原始的key、value地址__0x8112133e36d57ed9,0x803afe7f3fa3a5b8
2019-09-26 20:21:34.293365+0800 ARCMemory[14403:11067674] dic中key、value的地址__0x8112133e36d57ed9,0x803afe7f3fa3a5b8
2019-09-26 20:21:34.293496+0800 ARCMemory[14403:11067674] dic的地址__0x600001011f80
2019-09-26 20:21:34.293750+0800 ARCMemory[14403:11067674] copyDic的地址__0x600000538380
2019-09-26 20:21:34.293933+0800 ARCMemory[14403:11067674] copyDic中key、value的地址__0x8112133e36d57ed9,0x803afe7f3fa3a5b8
打印结果显示,只是生成的copyDic字典是新地址,此时对字典本身进行了copy操作,但是其它key、value地址均未发生改变,也就是说,字典内部的键值对仍旧是retain操作
NSMutableDictionary copy
只是对Dic本身进行了copy操作,字典内部的key、value均是retain操作,地址不变。
NSMutableDictionary mutableCopy
只是对Dic本身进行了copy操作,字典内部的key、value均是retain操作,地址不变。