copy 和 mutableCopy

retain 和 copy 的区别。

copy

copy是通过旧对象创建一个新对象,新对象引用计数器为1,与旧对象的引用计数无关。

retain

retain是创建一个指针,对象引用计数加1。retain 出来的指针和原对象的指针指向的内存地址是相同的。

如何实现copy

并不是所有对象都可以进行copy、mutableCopy 。对象如果可以被copy 则需要遵守NSCopying , 如果对象可以被mutableCopying 则需要遵从 NSMutableCopying。如果即可以被copy 也可以被mutableCopy 则需要同时遵守NSCopying 和 NSMutableCopying。

  • 遵守 NSCopying 需要实现 copyWithZone : 方法
  • 遵守 NSMutableCopying 需要实现 mutableCopyWithZone : 方法

值得注意的是一些API中的类已经遵守了NSCopying 协议或NSMutableCopying 协议,如NSArray等。

复制API中的对象

不可变对象的copy 是浅拷贝,这是拷贝源对象的指针,也就是retain.比如NSArray.
  1. NSArray *array = [NSArray array] ;
  2. // 对于不可变的对象copy只是浅拷贝,retain一下
  3. NSArray *arrayCopy = [array copy] ;
  4. // 通过输出得知两个对象的内存地址相同。
  5. NSLog(@"array retainCount = %lu , array == arrayCopy ? result = %i",[array retainCount],array == arrayCopy) ;
可变对象的copy是创建出新的对象,开辟新的内存空间,真正意义上的复制,如 NSMutableArray.
  1. NSMutableArray *array = [NSMutableArray array] ;
  2. // 对于可变的对象copy是深拷贝,开辟内存空间
  3. NSArray *arrayCopy = [array copy] ;
  4. // 通过输出得知两个对象的内存地址不同,是两块不同的内存空间
  5. NSLog(@"array retainCount = %lu , array == arrayCopy ? result = %i",[array retainCount],array == arrayCopy) ;

mutableCopy

针对不可变对象的mutableCopy,会进行深拷贝,开辟新的内存空间
  1. NSArray *array = [NSArray array] ;
  2. // 对于不可变对象的可变拷贝, 深拷贝,开辟内存空间
  3. NSMutableArray *arrayCopy = [array mutableCopy] ;
  4. // 通过输出得知两个对象的内存地址不同,是两块不同的内存空间
  5. NSLog(@"array retainCount = %lu , array == arrayCopy ? result = %i",[array retainCount],array == arrayCopy) ;

关于数组元素的拷贝

当我们深拷贝数组的时候,数组的元素是浅拷贝。

  1. //将一个可变字符串填充到数组
  2. NSMutableArray * arr = [NSMutableArray arrayWithObjects:[NSMutableString stringWithFormat:@"张三"] , nil];
  3. // 进行数组的copy
  4. NSMutableArray *arrayCopy = [arr copy];
  5. // 获得arr 的第一个元素
  6. NSMutableString *string = [arr objectAtIndex:0];
  7. // 修改第一个元素
  8. [string appendString:@"是个孩子"] ;
  9. // 输出拷贝数组的第一个元素,证明数组元素是浅拷贝.
  10. NSLog([arrayCopy objectAtIndex:0]) ; // 输出张三是个孩子.
如何对数组元素进行彻底的深拷贝?

使用归档技术,这种计数我们在归档的文章中详细讲解.

自定义对象如何copy ?

自定义对象想要被拷贝需要实现NSCopying、NSMutableCopying 。

  1. // Person 类
  2. @interface Person : NSObject <NSCopying,NSMutableCopying>
  3. @property NSObject *obj ;
  4. @end
copy : copyWithZone 方法。
  1. // 响应copy
  2. -(id) copyWithZone:(NSZone *)zone{
  3. // 初始化对象
  4. Person *p = [[[self class] allocWithZone:zone] init];
  5. // 属性拷贝
  6. p.obj = obj ;
  7. // 返回对象
  8. return p ;
  9. }
mutableCopy : mutableCopyWithZone 方法。
  1. // 响应mutableCopy
  2. -(id) mutableCopyWithZone:(NSZone *)zone{
  3. // 初始化对象
  4. Person *p = [[[self class] allocWithZone:zone] init];
  5. // 属性拷贝
  6. p.obj = obj ;
  7. // 返回对象
  8. return p ;
  9. }
关于代码中的[self class] allocWithZone

这是为了便于扩展性,当类被继承的时候,copyWithZone 等相关代码也会继承,这个时候使用 [self class] allocWithZone 可以更具有扩展性。

copy 和 继承

父类的copyWithZone
  1. // 父类的copy 响应方法
  2. -(id) copyWithZone:(NSZone *)zone{
  3. Person *person = [[[self class ] allocWithZone:zone]init];
  4. person.age = age;
  5. person.name = name;
  6. person.address = address ;
  7. return person ;
  8. }
子类的copyWithZone
  1. // 子类的copy 响应方法
  2. -(id) copyWithZone:(NSZone *)zone{
  3. // 先调用父类,让父类copyWithZone copy完父类属性
  4. Child *child = [super copyWithZone:zone] ;
  5. // copy子类属性
  6. child.childName = childName ;
  7. // 返回指针
  8. return child ;
  9. }
时间: 2024-08-24 10:33:59

copy 和 mutableCopy的相关文章

Copy和MutableCopy

//    一: copy 与 retain 的区别 //    谁才有引用计数的概念: //    1. 堆区空间才有引用计数概念. //    2. 堆区的对象才会有引用计数. //%ld: - 1           %lu:18446744073709551615 //retain:始终是浅拷贝.引用计数每次加一. //返回对象是否可变与被复制的对象保持一致. //copy:对于可变对象为深拷贝,引用计数不改变; //对于不可变对象是浅拷贝,引用计数每次加一. //始终返回一个不可变对象

Objective-C Objective-C中的指针,及对象的直接指向,copy和mutablecopy

1.Objective-C的指针世界 OC一直是人感觉比较变态的一门语言,为什么呢?因为它的每个变量都是指针型,多的都几乎让人忘了那个*的存在了. 所以常常a=b这个等号让我产生错觉,总以为a从b那拷贝了一份. 然而这的的确确,却是个指针.a这个变量存的内容是b所在的地址. 比如我定义了一个Student的Class,new了stu1和stu2,并把stu2=stu1,那当两者任何一个进行修改时,两个变量的内容都会修改. Student *stu1=[[Student alloc]init];

OC语法——Object-C retain、copy、mutableCopy的详细分析

OC语法中的retain.copy.mutableCopy 大家都基本知道它的基本意思,但是对于mutable类型和immutable类型的处理上有很多童鞋并没有真正测试过,今天就和大家分享下: 1.先来看下immutable类型的非容器类: NSString的retain.copy和mutableCopy的测试 NSString *string = @"abc"; NSString *retainString = [string retain]; NSString *copyStri

Objective-C语法之copy和mutablecopy

#pragma mark 演示字符串的copy //深拷贝--对象拷贝--内容拷贝(产生新对象)新对象计数器+1,原对象不变 void stringmutableCopy(){ //string = 1 NSString *string = [[NSString alloc]initWithFormat:@"age is %i", 10]; //str = 1 //产生了一个新对象,原对象的计数器不变 NSMutableString *str = [string mutableCopy

【OC学习-11】ARC和内存管理里面的alloc、assign、new、retain、copy、mutableCopy、release说明

一般我们在开发程序时,只管alloc,不需要管release,因为有ARC帮我们管理.但是在学习时仍需要了解:内存是有限的,在堆区分配了内存后,如果不需要,则要回收,不然内存不够引起崩溃. 所以原则是:有分配,就有回收.但是这个分配有可能分配好几次,那么回收怎么知道回收几次呢?这就是引用计数的作用.创建一个对象时,它自带了这个引用计数. (1)alloc.new.copy.mutableCopy和retain时,引用计数+1,即retainCount+1; (2)release时,引用计数ret

copy and mutableCopy

结论: 1, 深复制与浅复制 2,immutable和mutable 3,代码分析: #pragma mark - String - (void)stringCopyAndMutableCopy { NSString *originStr = @"123"; NSString *copyStr = [originStr copy];//浅复制 NSString *mutableCopyStr = [originStr mutableCopy];//深复制 NSLog(@"st

关于:1.指针与对象;2.深浅拷贝(复制);3.可变与不可变对象;4.copy与mutableCopy的一些理解

最近对深浅拷贝(复制)做了一些研究,在此将自己的理解写下来,希望对大家有所帮助.本人尚处在摸索阶段,希望各位予以指正. 本文包括如下方向的探索: 1.指针与对象: 2.深/浅拷贝(复制): 3.可变/不可变对象: 4.Objective-C中的copy与mutableCopy方法. 一.指针与对象 在初始学习编程的时候,对于绝大多数面向对象编程的语言,这都是个绕不开的重点与难点.非常惭愧的是对它的认识我一直是不够的,并且感觉这项技术有许多的内容可以挖掘.说这是面向对象编程的核心思想也不为过.很多

深浅拷贝的应用-copy、mutableCopy

ViewController.h #import <UIKit/UIKit.h> @interface ViewController : UIViewController //如果想让list成为一个可变的数组,需要把copy变成retain,因为copy之后的对象永远都只是一个不可变的对象 @property (nonatomic,copy)NSMutableArray *list; @end ViewController.m /* 拷贝:复制一个对象->变成另外一个对象 深拷贝:复制

不可变实例、可变实例、copy与mutableCopy

代码: #import <Foundation/Foundation.h> // 不论一个实例是不可变实例还是可变实例 // 通过向该实例发送copy消息,得到的实例是不可变实例 // 通过向该实例发送mutableCopy消息,得到的实例是可变实例 // 在非ARC环境下 // 通过向实例发送copy或mutableCopy消息得到的实例需要手工调用release或autorelease方法 void stringCopy(void); void stringMutableCopy(void