iOS 深拷贝、浅拷贝、自定义对象拷贝简介

copy语法的目的:改变副本的时候,不会影响到源对象;

深拷贝:内容拷贝,会产生新的对象。新对象计数器置为1,源对象计数器不变。

浅拷贝:指针拷贝,不会产生新的对象。源对象计数器+1。

拷贝有下面两个方法实现拷贝:

- (id)copy;
- (id)mutableCopy;

对象要实现copy,必须实现<NSCopying>协议
数组,字典,字符串都已经实现了<NSCopying>协议,以下以字符串为例:

1.不可变字符串调用copy实现拷(浅拷贝)

NSString *string = [[NSString alloc] initWithFormat:@"abcde"];
// copy产生的是不可变副本,由于源对象本身就不可变,所以为了性能着想,copy会直接返回源对象本身
// 源对象计数器会+1
// 在浅拷贝情况下,copy其实就相当于retain
NSString *str = [string copy];

2.不可变字符串调用mutableCopy实现拷贝,(深拷贝)

NSString *string = [[NSString alloc] initWithFormat:@"abcd"];
// 产生了一个新的对象,计数器为1。源对象的计数器不变。
NSMutableString *str = [string mutableCopy];//此时存在两个对象// str:1和// string:1
 // str和string不是相同对象
 // NSLog(@"%i", str == string);//0
 [str appendString:@" abcd"];//修改str不影响string
 NSLog(@"string:%@", string);
 NSLog(@"str:%@", str);

3.可变字符串调用copy实现拷贝(深拷贝)

NSMutableString *string = [NSMutableString stringWithFormat:@"age is %i", 10];
 // 会产生一个新对象,str计数器为1
 NSString *str = [string copy];

4.可变字符串的MutableCopy(深拷贝)

NSMutableString *string = [NSMutableString stringWithFormat:@"age is %i", 10];
// 会产生一个新对象,str计数器为1
NSMutableString *str = [string mutableCopy];
[str appendString:@"1234"];//修改新对象不影响原对象
NSLog(@"str:%@", str);
NSLog(@"string:%@", string);

5.拷贝自定义对象,下面以Student对象为例

a.Student要实现copy,必须实现<NSCopying>协议

b.实现<NSCopying>协议的方法:

- (id)copyWithZone:(NSZone *)zone

Student.h文件

@interface Student : NSObject <NSCopying>  

// copy代表set方法会release旧对象、copy新对象
// 修改外面的变量,并不会影响到内部的成员变量
// 建议:NSString一般用copy策略,其他对象一般用retain
@property (nonatomic, copy) NSString *name;  

+ (id)studentWithName:(NSString *)name;  

@end

Student.m文件

#import "Student.h"  

@implementation Student  

+ (id)studentWithName:(NSString *)name {
    // 这里最好写[self class]
    Student *stu = [[[[self class] alloc] init] autorelease];
    stu.name = name;  

    return stu;
}  

- (void)dealloc {
    [_name release];  

    [super dealloc];
}  

#pragma mark description方法内部不能打印self,不然会造成死循环
- (NSString *)description {
    return [NSString stringWithFormat:@"[name=%@]", _name];
}  

#pragma mark copying协议的方法
// 这里创建的副本对象不要求释放
- (id)copyWithZone:(NSZone *)zone {
    Student *copy = [[[self class] allocWithZone:zone] init];  

    // 拷贝名字给副本对象
    copy.name = self.name;  

    return copy;
}  

@end

拷贝Student

Student *stu1 = [Student studentWithName:@"stu1"];  

Student *stu2 = [stu1 copy];
stu2.name = @"stu2";  

NSLog(@"stu1:%@", stu1);
NSLog(@"stu2:%@", stu2);  

[stu2 release];

小结:

建议:NSString一般用copy策略,其他对象一般用retain;

只有一种情况是浅拷贝:不可变对象调用copy方法时,其他情况都为深拷贝;

时间: 2024-11-05 16:47:57

iOS 深拷贝、浅拷贝、自定义对象拷贝简介的相关文章

iOS开发——保存自定义对象数组、字典到文件

在ios中,要保存普通的数组到文件可以直接调用-wirteToFile:atomically:方法写入,并且可以通过NSArray的方法-initWithContentOfFile:来读文件初始化数组.然而,当要保存的数组中存储的数据对象是自定义对象时,就得通过对象归档的方法来实现了,具体来说 一.自定义对象实现归档协议,并实现方法- (id)initWithCoder:和方法- (void)encodeWithCoder: @interface CourseModel : CYZBaseMod

iOS --归档存储自定义对象

#import <Foundation/Foundation.h> @interface User : NSObject<NSCoding> //遵循NSCoding协议 /** name */ @property (nonatomic, copy) NSString *name; /** age */ @property (nonatomic, assign) NSInteger age; //自定义初始化方法 - (instancetype)initWithName:(NSSt

【iOS】浅拷贝和深拷贝

浅拷贝和深拷贝 浅拷贝即指针拷贝,可以认为是给一只狗加了一条绳子:深拷贝不但拷贝了对象的指针,还在系统中在分配了一块内存用来存放拷贝对象的内容,可以认为是产生了一条带绳子的新狗.即浅拷贝是两根绳子一条狗,深拷贝是两根绳子两条狗且每只狗对应各自的绳子. 图示: 深浅拷贝取决于拷贝后的对象是不是和被拷贝对象的地址相同,如果不同,则产生了新的对象,即为深拷贝.如果不同,则只是指针拷贝,相当于retain一次原对象,即为浅拷贝. copy与mutableCopy copy复制后的对象是不可变对象,mut

iOS 自定义对象及子类及模型套模型的拷贝、归档存储的通用代码

一.runtime实现通用copy 如果自定义类的子类,模型套模型你真的会copy吗,小心有坑. copy需要自定义类继承NSCopying协议 #import <objc/runtime.h> - (id)copyWithZone:(NSZone *)zone { id obj = [[[self class] allocWithZone:zone] init]; Class class = [self class]; while (class != [NSObject class]) {

探讨一下iOS中深拷贝&amp;浅拷贝&amp;copy的那些事儿

什么是深拷贝?什么是浅拷贝? 为什么经常看到字符串属性要这样定义,那个copy是神马意思? @property(nonatomic,copy)NSString* name; 为什么下面的写法是错误的? @property(nonatomic,copy)NSMutableString* name; copyWithZone方法又到底是干嘛用的? 接下来,我们将一起,一步一步的去揭晓问题的答案. Copy到底是个啥? 其实我们真的没必要把copy想的太高深.它之所以叫copy,其终极目的已不言而喻,

iOS:深拷贝与浅拷贝

copy与retain的区别:copy是创建一个新对象,retain是创建一个指针,引用对象计数加1.Copy属性表示两个对象内容相同,新的对象retain为1 ,与旧有对象的引用计数无关,旧有对象没有变化.copy减少对象对上下文的依赖. retain属性表示两个对象地址相同(建立一个指针,指针拷贝),内容当然相同,这个对象的retain值+1也就是说,retain 是指针拷贝,copy 是内容拷贝. 当然在ios中并不是所有的对象都支持copy,mutableCopy,遵守NSCopying

iOS深拷贝与浅拷贝

概念 对象拷贝有两种方式:浅复制和深复制.顾名思义,浅复制,并不拷贝对象本身,仅仅是拷贝指向对象的指针:深复制是直接拷贝整个对象内存到另一块内存中. 如图详解: 再简单些说:浅复制就是指针拷贝:深复制就是内容拷贝. 集合的浅拷贝 (shallow copy) 集合的浅复制有非常多种方法.当你进行浅复制时,会向原始的集合发送retain消息,引用计数加1,同时指针被拷贝到新的集合. 浅拷贝的例子: NSArray *shallowCopyArray = [someArray copyWithZon

IOS开发复制的总结(深拷贝浅拷贝区别)

1.复制可变字符串 NSMutableString * city = [NSMutableString stringWithString:@"北京"]; //复制可变副本 NSMutableString * cityCopy = [city mutableCopy]; //修改副本 [cityCopy replaceCharactersInRange:NSMakeRange(0, 2) withString:@"临沧"]; //输出看到原字符串没有改变 当前的改变

IOS的浅拷贝和深拷贝

什么是深拷贝和浅拷贝 浅拷贝:就是指针的复制,拷贝的指针跟原指针指向内存中的同一个位置的对象.至于对象的引用计数值是否+1,就是看拷贝的指针赋给给的变量是Strong类型的,还是week类型的. 如果是 strong类型,那么被拷贝的对象的内存计数值会+1,如果赋值给了weak类型的变量,那么被拷贝的对象的内存计数值会保持不便. 深拷贝:将内存中的对象拷贝一份,放到一个新的位置,并将这个指向这个新位置的指针指赋值给另外一个变量. 判断拷贝类型,关键的依据是指针所指向的对象在内存中的地址. IOS