深浅复制

copy:

返回由copyWithZone:返回的对象。

- (id)copy

返回值:

对象由NSCopying协议方法  copyWithZone:返回;

描述:

这是采用了NSCopying协议的对象的简便方法。如果对象没有实现copyWithZone:,将会抛出异常。NSObject自己并不支持 NSCopying协议,他的子类必须支持NSCopying协议,并实现 copyWithZone:方法。子类中的copyWithZone:应该先调用父类中的版本,除非子类是直接继承自NSObject


mutableCopy

返回由 mutableCopyWithZone:返回的对象,其中zone参数为nil。

- (id)mutableCopy;

返回值:

对象由NSMutableCopying协议方法 mutableCopyWithZone:返回,zone参数为nil。

描述:

这是采用了 NSMutableCopying协议的类的便利方法,如果这个类型没有实现mutableCopyWithZone:方法,将会产生异常。


验证:非可变对象不能用mutableCopy;

例子:

CopyTestObject 继承自 NSObject

代码:

    CopyTestObject* obj = [[CopyTestObject alloc] init];
    CopyTestObject* copyObj = [obj copy];
    NSLog(@"obj address:%p",obj);
    NSLog(@"obj address:%p",copyObj);
运行正常,输出

 obj address:0xa06a6a0
 obj address:0xa069b80

代码:

CopyTestObject* obj = [[CopyTestObject alloc] init];
CopyTestObject* mutableCopyObj = [obj mutableCopy];

出现异常NSInvalidArgumentException

reason: '-[CopyTestObject mutableCopyWithZone:]: unrecognized selector sent to instance 0x9a847d0'


验证:可变对象,用copy得到的为非可变对象。用mutableCopy得到可变对象。

例子2:

    NSArray* array = [[NSArray alloc] init];
    NSArray* copyArray = [array copy];
    
    NSMutableArray* mutArray = [[NSMutableArray alloc] init];
    NSMutableArray* copyMutArray = [mutArray copy];
    
    NSMutableArray* mutArray2 = [[NSMutableArray alloc] init];
    NSMutableArray* copyMutArray2 = [mutArray mutableCopy];
    
    NSLog(@"array class:%@",[NSString stringWithUTF8String:object_getClassName(array)]);
    NSLog(@"copyArray class:%@",[NSString stringWithUTF8String:object_getClassName(copyArray)]);
    
    NSLog(@"mutArray class:%@",[NSString stringWithUTF8String:object_getClassName(mutArray)]);
    NSLog(@"copyMutArray class:%@",[NSString stringWithUTF8String:object_getClassName(copyMutArray)]);
    
    NSLog(@"mutArray2 class:%@",[NSString stringWithUTF8String:object_getClassName(mutArray2)]);
    NSLog(@"copyMutArray2 class:%@",[NSString stringWithUTF8String:object_getClassName(copyMutArray2)]);

输出:

2014-04-11 10:38:27.257 testCopy[4759:a0b] array class:__NSArrayI
2014-04-11 10:38:27.257 testCopy[4759:a0b] copyArray class:__NSArrayI
2014-04-11 10:38:27.257 testCopy[4759:a0b] mutArray class:__NSArrayM
2014-04-11 10:38:27.258 testCopy[4759:a0b] copyMutArray class:__NSArrayI
2014-04-11 10:38:27.258 testCopy[4759:a0b] mutArray2 class:__NSArrayM
2014-04-11 10:38:27.258 testCopy[4759:a0b] copyMutArray2 class:__NSArrayM

NSCopying协议:

NSCopying协议声明了一个方法来拷贝一个对象。拷贝的确切意义可能根据不同个类型而变化,但是拷贝的对象必须是一个功能独立的对象,其中包含的值和原对象相同在拷贝完成时。拷贝产生的对象被调用者保留,以在适当的时候释放他。

NSCopying定义了一个方法copyWithZone:,但是拷贝通常通过简便函数copy调用。copy函数在所有继承自NSObject的对象中都有定义,用来方便的调用copyWithZone:,其中参数为默认zone(内存区域)。

在如下情况你可以选择实现协议:

1.实现NSCopying来使用alloc和init,在那些没有继承copyWithZone:的类别中。

3.实现NSCopying,在某些内容不可变的类别中,以保留计数来代替创建一个新的拷贝。(自定义对象的拷贝含义)

如果子类从父类继承NSCopying,而且声明了额外的成员变量,子类必须去重写copyWithZone:,以正确的操作自己的成员变量,当然要先调用父类的实现。

实例方法:

- (id)copyWithZone:(NSZone *)zone

返回一个新的实例,这个实例是发送者的拷贝。

参数:

内存中被分配给新实例的一块区域,如果zone的值为NULL,则新实例从默认的区域中分配,这块默认的区域由NSDefaultMallocZone返回。

描述:

拷贝返回一个不可变类型,如果接收者需要考虑可变与不可变。否则复制的具体情况由类型决定。


NSMutableCopying协议:

NSMutableCopying协议声明了了一个方法来提供可变对象的副本。只有定义了可变与不可变差别的类型能采用改协议。那些没有这些差别的类型,应采取NSCopying协议。

NSMutableCopying协议中声明了一个方法,mutableCopyWithZone:,但是可变拷贝通常通过便利方法mutableCopy来调用。mutableCopy方法在所用的NSObject对象中都有定义,以便更方便的调用mutableCopyWithZone:方法。

如果子类从父类继承NSMutableCopying协议,并且声明了额外的实例变量,子类需要去重构 mutableCopyWithZone:来正确的操作他自己的实例变量,当然首先应该调用父类的实现。

实例方法:

- (id)mutableCopyWithZone:(NSZone *)zone

参数

zone

内存中被分配给新实例的一块区域,如果zone的值为NULL,则新实例从默认的区域中分配,这块默认的区域由NSDefaultMallocZone返回。

描述

这个拷贝返回的是可变对象,无论原对象是可变的或不可变的。

关于数组的深浅拷贝

https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Collections/Articles/Copying.html

无论用copy还是mutablecopy得到的都是数组的浅拷贝。

数组的深拷贝

NSArray *deepCopyArray=[[NSArray alloc] initWithArray:someArray copyItems:YES];
其中数组中的元素要实现方法:

- (id)copyWithZone:(NSZone *)zone

验证例子:

@interface CopyTestObject : NSObject

@property (nonatomic, copy)NSString* thename;
@property (nonatomic, retain)NSString* myname;

@end

@implementation CopyTestObject

- (id)copyWithZone:(NSZone *)zone
{
    CopyTestObject *result = [[[self class] allocWithZone:zone] init];
    result.myname = [self.myname copy];
    result.thename = [self.thename copy];
    return result;
}

@end

    NSMutableArray* mutArray =[[NSMutableArray alloc] init];
    {
        CopyTestObject* obj = [[CopyTestObject alloc] init];
        obj.thename = @"name1111111";
        obj.myname = @"myname1111111";
        [mutArray addObject:obj];
    }
    {
        CopyTestObject* obj = [[CopyTestObject alloc] init];
        obj.thename = @"name22222222";
        obj.myname = @"myname22222222";
        [mutArray addObject:obj];
    }
    
    NSArray* copyArray = [[NSMutableArray alloc] initWithArray:mutArray copyItems:YES];
    
    CopyTestObject* obj1 = [mutArray objectAtIndex:0];
    obj1.thename = @"name change";
    obj1.myname = @"myname change";
    
    for (CopyTestObject* obj in mutArray) {
        NSLog(@"mutArray:%@        %@",obj.thename,obj.myname);
    }
    for (CopyTestObject* obj in copyArray) {
        NSLog(@"copyArray:%@        %@",obj.thename,obj.myname);
    }
输出:

2014-04-11 10:49:12.581 testCopy[4779:a0b] mutArray:name change        myname change
2014-04-11 10:49:12.582 testCopy[4779:a0b] mutArray:name22222222        myname22222222
2014-04-11 10:49:12.582 testCopy[4779:a0b] copyArray:name1111111        myname1111111
2014-04-11 10:49:12.582 testCopy[4779:a0b] copyArray:name22222222        myname22222222




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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值