suchen

Heim  >  Fragen und Antworten  >  Hauptteil

objective-c - NSArray *array = otherarray;是深拷贝还是浅拷贝?该怎么理解


NSArray *array = [[NSArray alloc] initWithObjects:@23, @"re", nil] ;
NSArray *arr2 = array;
NSLog(@"%lu",(unsigned long)[array retainCount]);
NSLog(@"%lu",(unsigned long)[arr2 retainCount]);

结果是 1,1


NSArray *array = [[NSArray alloc] initWithObjects:@23, @"re", nil] ;
NSArray *arr2 = [array copy];
NSLog(@"%lu",(unsigned long)[array retainCount]);
NSLog(@"%lu",(unsigned long)[arr2 retainCount]);

结果是 2,2


NSArray *array = [[NSArray alloc] initWithObjects:@23, @"re", nil] ;
NSArray *arr2 = [array mutbaleCopy];
NSLog(@"%lu",(unsigned long)[array retainCount]);
NSLog(@"%lu",(unsigned long)[arr2 retainCount]);

结果是1,1

所以应该怎么理解???

PHPzPHPz2766 Tage vor492

Antworte allen(2)Ich werde antworten

  • PHPz

    PHPz2017-04-24 09:13:20

    NSArray *arr2 = array;
    

    上面这段代码,既不是深拷贝也不是浅拷贝,这只是一个指针赋值,它们指向的是同一块内存。


    NSArray *arr2 = [array copy];
    

    上面这段代码,理论上 array 创建了一份浅拷贝,可实际上并没有发生任何拷贝,仅仅做了一次 retain

    这是因为 NSArray 是一个不可被修改的只读数组,它在实现 NSCopying protocol 的时候很机(tou)智(lan)的仅仅做了一次 retain 而没有创建任何新对象,所以造成 arrayarr2 引用计数都变成 2,有些违反直觉。

    注意,此时 arrayarr2 是指向同一片内存的,通过打印指针地址可以明显的看出来。


    NSArray *arr2 = [array mutableCopy];
    

    上面这段代码,mutableCopy 返回的是一个 NSMutableArray,这时候 NSArray 没什么巧可取,就是老老实实的创建了一个新的 NSMutableArray 对象,array 指向 NSArrayarr2 指向新创建的 NSMutableArray,所以引用计数都是 1。


    回到深拷贝和浅拷贝,对于一个容器来说,如果拷贝时容器里面的对象仅仅增加了引用计数,那么就是浅拷贝;否则,如果为每一个对象创建了新对象,那么就是深拷贝。

    题主应该用 NSMutableArray 来尝试才能得到清晰正确的结果,NSArray 这种 immutable 的容器无法看出想要的效果。

    顺便一提,NSMutableArraycopy 是浅拷贝。

    Antwort
    0
  • PHP中文网

    PHP中文网2017-04-24 09:13:20

    说句题外话,断点、LLDB调试或者打印观察内存地址,可以帮助我们更好的理解这里面的机制。

    Antwort
    0
  • StornierenAntwort