浅拷贝、深拷贝

一.不可变拷贝与可变拷贝

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

原文地址:https://www.cnblogs.com/huen/p/3535437.html