iOS 深拷贝 浅拷贝

1,045 阅读2分钟

深拷贝 浅拷贝

浅拷贝

浅拷贝并不是拷贝对象本身,而是对指向对象的指针进行拷贝,但还是指向同一块堆内存中指针指向的对象

浅拷贝.png

可以看出浅拷贝中栈内存中指针对象的地址改变了,但还是指向相同的一块堆内存地址

深拷贝

直接拷贝对象到内存中的一块区域,然后把新对象的指针指向这块内存。

深拷贝.png

可以看出深拷贝是直接拷贝对象到内存中的一块区域(分配了一块新的内存空间),然后把新对象的指针指向这块内存,原对象和被赋值对象互不影响。

深拷贝与浅拷贝的本质区别

在于是否在堆内存中开辟新的内存空间。

区分深拷贝与浅拷贝

主要从 容器类和 非容器 类着手,不管是容器类还是非容器类都有可变对象和不可变对象,所以分为四种:

  • 非容器类不可变对象:NSString
  • 非容器类可变对象:NSMutableString
  • 容器类不可变对象:NSArray
  • 容器类可变对象:NSMutableArray

结论

[object copy]:对于可变对象为深拷贝,不可变对象为浅拷贝。
[object mutableCopy]:始终都是深拷贝。

测试代码

// 对不可变对象 copy 为浅拷贝

    {

        NSString *objc = @"111";

        NSString *objc1 = [objc copy];

        NSString *objc2 = [objc mutableCopy];

        NSLog(@"不可变对象copy为浅拷贝");

        NSLog(@"堆内存地址%p - %p", objc, &objc);

        NSLog(@"copy堆内存地址%p - %p", objc1, &objc1);

        

        NSLog(@"mutalCopy为深拷贝");

        NSLog(@"mutableCopy堆内存地址%p - %p", objc2, &objc2);

        NSLog(@"====================");

    }

    

    {

        NSArray *objc = @[@1];

        NSArray *objc1 = [objc copy];

        NSArray *objc2 = [objc mutableCopy];

    }

    

    // 可变对象 copy 为深拷贝

    {

        NSMutableString *objc = [[NSMutableString alloc] initWithString:@"111"];

        NSString *objc1 = [objc copy];

        NSString *objc2 = [objc mutableCopy];

        

        NSLog(@"可变对象copy、muatalCopy都是深拷贝");

        NSLog(@"堆内存地址%p - %p", objc, &objc);

        NSLog(@"copy堆内存地址%p - %p", objc1, &objc1);

        NSLog(@"mutableCopy堆内存地址%p - %p", objc2, &objc2);

        NSLog(@"====================");

    }

    

    {

        NSMutableArray *objc = [NSMutableArray arrayWithArray:@[@1]];

        NSArray *objc1 = [objc copy];

        NSArray *objc2 = [objc mutableCopy];

    }