本文介绍: 浅拷贝:只创建一个新的指针指向指针指向内存拷贝创建一个新的指针,并开辟新的内存空间内容拷贝自原指针指向的内存,并指向假设我们要对一个不可变对象进行不可变copy(原来的对象可变,新对象也不可变)。就没必要给新对象新建一块内存,反正大家都不可以对这个对象进行改变,那都使用一个就可以。所以iOS系统规定浅拷贝引用计数器加1就行。而需要给新对象开闭内存空间的,就是深拷贝。浅拷贝即指针拷贝可以认为是给一只狗加了一条绳子;深拷贝不但拷贝了对象的指针,还在系统中在分配了一块内存用来存放拷贝对象的


一、深拷贝和浅拷贝

浅拷贝:只创建一个新的指针,指向原指针指向的内存
深拷贝:创建一个新的指针,并开辟新的内存空间,内容拷贝自原指针指向的内存,并指向它
假设我们要对一个不可变的对象进行不可变copy(原来的对象不可变,新对象也不可变)。就没必要给新对象新建一块内存,反正大家都不可以对这个对象进行改变,那都使用一个就可以。所以iOS系统规定浅拷贝引用计数器加1就行。而需要给新对象开闭内存空间的,就是深拷贝。

在这里插入图片描述

copy得到的类型一定是不可变的 mutableCopy得到的类型一定是可变的 使用mutable,都是深拷贝(不管是拷贝类型还是拷贝方法);但是copy也有深拷贝;

浅拷贝即指针拷贝,可以认为是给一只狗加了一条绳子;深拷贝不但拷贝了对象的指针,还在系统中在分配了一块内存用来存放拷贝对象的内容可以认为是产生了一条带绳子的新狗。即浅拷贝是两根绳子一条狗,深拷贝是两根绳子两条狗且每只狗对应各自的绳子。
1.浅拷贝

int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSString* str = @"Objective-C";
        NSString* str2 = [str copy];
        NSLog(@"str = %@, str2 = %@", str, str2);
    }
    return 0;
}

运行结果
在这里插入图片描述

当创建一个NSArray数组

NSArray* arr1 = [NSArray arrayWithObjects:@"苹果", @"桃子", @"葡萄", nil];

mutbaleCopy复制一个不同类型的NSMutableArray数组

NSMutableArray* arr2 = [arr1 mutableCopy];

打印两者的指针地址,不同

NSLog(@"arr1 = %p, arr2 = %p", arr1, arr2);

运行结果
在这里插入图片描述

打印arr1和arr2保存元素,相同

        NSLog(@"======打印arr1中的元素======");
        for (id object in arr1) {
            NSLog(@"%@", object);
        }
        NSLog(@"======打印arr2中的元素======");
        for (id object in arr2) {
            NSLog(@"%@", object);
        }

运行结果
在这里插入图片描述

总结:创建出了一个新的对象,指针地址自然就不同,但副本中的元素都和被复制的对象中的元素相同,所以它是一个深复制

二、copy基本概念

1.什么是copy

copy的字面意思是“复制”、“拷贝”,是一个产生副本过程

常见的复制有:文件复制

作用: 利用一个源文件产生一个副本文

特点:
修改文件内容
修改本文件的内容,不会影响文件

OC中的copy

作用: 利用一个源对象产生一个副本对象

特点:
修改源对象的属性行为,不会影响副本对象
修改副本对象的属性行为,不会影响源对象

2.copy与mutableCopy

一个对象可以调用copymutableCopy方法来创建一个副本对象
copy:创建的是不可变副本(如NSString、NSArray、NSDictionary
mutableCopy:创建的是可变副本NSMutableString、NSMutableDictionary

copy复制后的对象是不可变对象 mutableCopy复制后的对象是可变对象,与原始对象是否可变无关。

使用copy功能的前提
copy需要遵守NSCopying协议实现copyWithZone:方法

@protocol NSCopying
- (id)copyWithZone:(NSZone*)zone;
@end

使用mutableCopy功能的前提
需要遵守NSMutableCopying协议实现mutableCopyWithZone:方法

@protocol NSmutableCopying
- (id)mutableCopyWithZone:(NSZone*)zone;
@end
int main(int argc, const char * argv[]) {
    @autoreleasepool {
        NSString* str = @"Objective-C";
        NSMutableString* str2 = [str mutableCopy];
        NSLog(@"str = %@, str2 = %@", str, str2);
    }
    return 0;
}

运行结果

在这里插入图片描述

分析
上面代码使用mutableCopy对str进行复制,所产生的新的对象副本类型是NSMutableString类型的,所以要新创建一个NSMutableString类型的str2,将刚才产生的副本存入

1.如果是通过不可变对象调用copy方法,那么不会生成一个新的对象原因:因为原来的对象是不能修改的,拷贝出来的对象也是不能修改的,既然两个都不能修改,所以永远不能影响到另外一个对象,那么已经符合需求(OC为了对内存进行优化,就不会生成一个新的对象)
2.OC中有部分对象已经遵守了NSCopyNSMutableCopy两个协议,如NSString。但如果是自定义的对象,如自定义一个person*对象,并不遵守这两个协议

原文地址:https://blog.csdn.net/weixin_61558111/article/details/125246723

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。

如若转载,请注明出处:http://www.7code.cn/show_11435.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注