iOS开发之OC入门(copy)

copy深/浅拷贝

即指针拷贝,是对内存地址的复制,让目标对象指针和源对象指向同一片内存空间,但是拷贝可变对象为深拷贝

mutableCopy深拷贝

即内容拷贝,指拷贝对象的具体内容,而内存地址是重新分配的,两个对象虽然存的值是相同的,但是内存地址不一样,两个对象也互不影响,互不干涉
mutableCopycopy是一个方法,定义在NSObject类中,用于拷贝对象

copy和mutableCopy

  • 由于NSString的特殊性,其数据存放在常量区,同一数据指针指向的地址是一样的
    NSString *str1 = @"str";
    NSString *str2 = @"str";
    NSLog(@"%p,%p",str1,str2);//同个地址
    
    NSArray *arr1 = @[str1,str2];
    NSArray *arr2 = @[str1,str2];
    NSLog(@"%p,%p",arr1,arr2);//不同地址
    
输出结果:
2022-03-08 18:34:18.817479+0800 Music[6262:471008] 0x100b9c070,0x100b9c070
2022-03-08 18:36:47.801387+0800 Music[6302:473278] 0x600000135e20,0x600000136260
  • 不可变数据做拷贝
	// 不可变数据
    NSArray *arr1 = @[@1,@2]; 
    NSArray *arr2 = [arr1 copy]; // 浅拷贝
    NSMutableArray *arr3 = [arr1 mutableCopy]; // 深拷贝
    NSLog(@"%p,%p,%p",arr1,arr2,arr3);
    
输出结果:
2022-08-23 10:37:20.773046+0800 Music[7322:3133638] 0x282c1b560,0x282c1b560,0x282242610
  • 可变数据做拷贝
    // 可变数据
    NSMutableArray *arr1 = [NSMutableArray array];
    [arr1 addObject:@1];
    
    NSArray *arr2 = [arr1 copy]; // 深拷贝
    NSMutableArray *arr3 = [arr1 mutableCopy]; // 深拷贝
    NSLog(@"%p,%p,%p",arr1,arr2,arr3);

输出结果:
2022-08-23 10:39:48.850628+0800 Music[7327:3135287] 0x281965470,0x281585ec0,0x281966b20
  • copy是拷贝为不可变对象,mutableCopy是拷贝为可变对象
  • 对不可变的数组、字典、集合等集合类对象,copy 是指针拷贝,mutablecopy 是内容拷贝
  • 对于可变的数组、字典、集合等集合类对象,copy,mutablecopy 都是内容拷贝

字符串对象拷贝的引用计数器问题

  • 存储在常量区的字符串对象是不允许被回收的,所以存储在常量区的字符串对象的引用计数器是一个超大是数,并且retain和release无效
  • 若字符串存储在堆区,这个字符串对象和普通的对象是一样的,引用计数器默认是1
  • 浅拷贝,对象的引用计数器+1,深拷贝,原来的对象的引用计数器不变,新对象引用计数器+1

自己的类具备对象拷贝能力

  • copy方法内部调用了另一个方法copyWithZone,这个方法是定义在NSCoping协议之中
  • 深拷贝:重新创建一个对象,复制返回
  • 浅拷贝:直接返回self
@interface Person :NSObject<NSCoping>
...
@property(nonatomic,copy)NSString *name;
@end

@implementation Person
-(id)copyWithZone:(NSZone *)zone
{
//深拷贝
Person *p1 = [Person new];
p1.name = _name;
return p1;

//浅拷贝
return self;
}

属性中的strong和copy

  • 属性中 copy 关键字的作用就是调用被赋值给属性的对象的copyWithZone方法,并将返回值赋值给属性
  • 对不可变的数组、字典、集合等集合类对象,都是指针拷贝
  • 对于可变的数组、字典、集合等集合类对象,strong是指针拷贝,copy是内容拷贝
// 可变数据举例
@property (nonatomic,strong) NSMutableString * StrongName;
@property (nonatomic,copy) NSMutableString * name;
----------------------------------------------------
    NSMutableString *str = [NSMutableString new];
    [str appendString:@"str"];
    NSLog(@"%p,%@",str,str);
    
    self.name = str;
    self.StrongName = str;
    
    [str appendString:@"!!!"];
    NSLog(@"%p,%@",str,str);
    NSLog(@"%p,%@",self.name,self.name);
    NSLog(@"%p,%@",self.StrongName,self.StrongName);
----------------------------------------------------   
输出结果:
2022-03-10 23:03:24.466102+0800 Music[3617:132644] 0x600000436250,str
2022-03-10 23:03:24.466167+0800 Music[3617:132644] 0x600000436250,str!!!
2022-03-10 23:03:24.466230+0800 Music[3617:132644] 0x963cbe8a3f6c64e4,str
2022-03-10 23:03:24.466274+0800 Music[3617:132644] 0x600000436250,str!!!

参考文章

iOS:copy的本质

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值