美文网首页
Collection对象里的内存管理语义

Collection对象里的内存管理语义

作者: C_HPY | 来源:发表于2019-09-26 20:38 被阅读0次

    第一部分 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类型

    image.png

    上述是在键为可变类型时的结果,再看键为不可变类型的情况:

        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”操作


    image.png

    值得注意的是如果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操作,地址不变。

    NSArray/NSMutableArray 进行copy、mutableCopy时的内存管理语义与上述字典完全一致

    相关文章

      网友评论

          本文标题:Collection对象里的内存管理语义

          本文链接:https://www.haomeiwen.com/subject/ejbnuctx.html