一.不可变拷贝与可变拷贝
1.系统对象(集合、字符串、二进制数据)的不可变和可变拷贝:
- copy方法:对对象不可变拷贝,返回1个不可变拷贝。
- mutableCopy方法:对对象可变拷贝,返回1个可变对象。
2.自定义类的不可变拷贝和可变拷贝:
- 对对象copy方法操作需实现协议<NSCopying>的-(id)copyWithZone:方法,不然程序会蹦。
- 对对象mutableCopy方法操作需实现协议<NSMutableCopying>的-(id)mutableCopyWithZone:方法,不然程序也会蹦。(通常只用不可变拷贝就可以满足需求,可变拷贝不常用)
3.
copy方法:
- 对不可变对象进行不可变拷贝操作,两者内存地址一致,由于copy返回的是不可变副本,系统只生成一份内存资源,此时的copy只是浅复制,和retain作用完全一样。
- 对可变对象进行不可变拷贝操作,两者内存地址不一致,引用计数始终为1,与原对象的引用计数无关,返回的是一个新对象。
mutableCopy方法:
引用计数始终为1,与原对象的引用计数无关,返回一个新对象。(该新对象可变,对源对象不影响)
二.深拷贝与浅拷贝
1.
浅拷贝:拷贝引用对象的指针。(指针的原因,改变其值对原对象有影响)
深拷贝:拷贝引用对象的内容。(拷贝一份副本,改变其值对原对象不影响)
2.对象的深、浅拷贝:
- 浅拷贝:对对象的一层(即不包括对象的属性)拷贝是内容拷贝。即只拷贝了对象,没有拷贝属性(只是引用指针)。
- 深拷贝:对对象的每一层拷贝都是内容拷贝。即拷贝了对象也拷贝了属性。(通过集合是否copyItems触发<NSCopying>协议的allocWithZone:方法或归档写入缓存区实现)
Student.h
#import <Foundation/Foundation.h> @interface Student : NSObject <NSCopying,NSCoding> { NSString *_name; int _age; } @property(nonatomic,assign)int age; -(void)setName:(NSString *)aName; -(NSString *)name; @end
Student.m
#import "Student.h" @implementation Student @synthesize age = _age; -(void)setName:(NSString *)aName { if (_name != aName) { [_name release]; _name = [aName copy]; } } -(NSString *)name { return _name; } //NSCopying Delegate Method -(id)copyWithZone:(NSZone *)zone { Student *stu = [[Student allocWithZone:zone]init];//新创建一个副本对象 stu.name = self.name; stu.age = self.age; return [stu autorelease]; } //编码 -(void)encodeWithCoder:(NSCoder *)aCoder { [aCoder encodeObject:_name forKey:@"name"]; [aCoder encodeInteger:_age forKey:@"age"]; } //解码 -(id)initWithCoder:(NSCoder *)aDecoder { self = [super init]; if (self) { self.name = [aDecoder decodeObjectForKey:@"name"]; self.age = [aDecoder decodeIntegerForKey:@"age"]; } return self; } -(NSString *)description// 当用%@输出该对象时自动调用 { return [NSString stringWithFormat:@"my name is %@,my age is %d",self.name,self.age ]; } -(void)dealloc { [_name release]; [super dealloc]; } @end
AppDelegate.m
NSMutableArray *stuArray = [[NSMutableArray alloc]initWithCapacity:10]; for (int i = 0;i < 10 ;i++) { Student *stu1 = [[Student alloc]init]; stu1.name = [NSString stringWithFormat:@"man%d",i]; stu1.age = i; [stuArray addObject:stu1]; [stu1 release]; }
// 1.浅拷贝
// NSMutableArray *arr2 = [[NSMutableArray alloc]initWithArray:stuArray];//浅拷贝 // [[arr2 objectAtIndex:0] setName:@"superMan"]; // NSLog(@"%@",arr2); // NSLog(@"%@",stuArray);
// 深拷贝:通过集合的copyItems触发<NSCopying>协议实现深拷贝 // NSMutableArray *arr3 = [[NSMutableArray alloc]initWithArray:stuArray copyItems:YES];//完全拷贝,实现<NSCopying>协议 // [[arr3 objectAtIndex:0] setName:@"batMan"]; // NSLog(@"%@,arr3 = %p",arr3,arr3); // NSLog(@"%@,stu = %p",stuArray,stuArray); //2.通过归档实现深拷贝(关于路径的部分不用写,NSData作缓冲区) NSData *data = [NSKeyedArchiver archivedDataWithRootObject:stuArray]; NSMutableArray *arr4 = [NSKeyedUnarchiver unarchiveObjectWithData:data]; [[arr4 objectAtIndex:0] setName:@"outeMan"]; NSLog(@"%@",arr4); NSLog(@"%@",stuArray);
转:http://www.cnblogs.com/eagle927183/p/3462439.html