iOS OC NSCopying 协议

一  NSCopying 协议

    想让自己的类支持拷贝操作(copy),就需要实现NSCopying协议该协议中有个方法:

-(id)copyWithZone:(NSZone *)zone

    zone是之前开发程序程序时,会把内存分成不同的 zone ,而对象会创建在zone 中。现在不用了,每个程序只有一个区-默认区(default zone),不用考虑zone参数


    copy方法由NSObject实现,该方法只是以 默认区 为参数来调用 copyWithZone: 我们总是想覆写copy方法,其实真正需要实现的却是 copyWithZone: 方法,这是需要注意的地方。若想使某个类支持拷贝功能,声明该类遵从NSCopying协议,并实现其中的方法即可。


    类分为可变版本与不可变版本,那么就应该实现NSMutableCopying,若采用此模式,则在可变类中覆盖 copyWithZone 方法时,不要返回可变的拷贝,而应该返回不可变的版本。无论当前实例是否可变,若需要获取可变版本的拷贝,都应该调用mutableCopy方法,若需要不可变的拷贝,则通过copy方法来获取


二 代码

    EOCCopying.h

==EOCCopying.h
#import <Foundation/Foundation.h>

@interface EOCCopying : NSObject<NSCopying>

/*name*/
@property (nonatomic, copy ) NSString *name;


/*mutable array*/
@property (nonatomic, copy ) NSMutableArray *array;


-initWithName:(NSString *)name;


//深拷贝
-(id)deepCopy;

@end


    EOCCopying.m

//
//  EOCCopying.m
//  EOC
//
//

#import "EOCCopying.h"

@implementation EOCCopying

-(id)initWithName:(NSString *)name
{
	
	self = [super init];
	if (self) {
		_name = name;
		_array = [NSMutableArray new];
	}
	return self;
}




-(id)copyWithZone:(NSZone *)zone
{
	EOCCopying *copy = [[[self class] allocWithZone:zone] initWithName:_name];
//	copy.array = [_array mutableCopy];
//	copy.array = [_array copy];
	
	//深拷贝
	copy->_array = [[NSMutableArray alloc]initWithArray:_array copyItems:YES];
	
	return self;
}


-(id)deepCopy
{
	EOCCopying *copy = [[[self class] alloc] initWithName:_name];
	
	//深拷贝
	copy->_array = [[NSMutableArray alloc]initWithArray:_array copyItems:YES];
	
	return self;
}
@end


  main.m

//
//  main.m
//  EOC
//
//

#import <Foundation/Foundation.h>
#import "EOCCopying.h"

int main(int argc, const char * argv[]) {
	@autoreleasepool {
		
		EOCCopying *obj = [[EOCCopying alloc]initWithName:@"COPY ---"];
		EOCCopying *cop = [obj deepCopy];
		
		
		NSLog(@"obj.name=%@",obj.name);
		NSLog(@"cop.name=%@",cop.name);
		
		
		[obj.array addObject:@"1"];
		NSLog(@"obj.array[0]=%@",obj.array[0]);
		obj.array[0] = @"一";
		NSLog(@"cop.array[0]=%@",cop.array[0]);
		NSLog(@"obj.array[0]=%@",obj.array[0]);
		
		
		[cop.array addObject:@"2"];
		NSLog(@"cop.array[1]=%@",cop.array[1]);
		NSLog(@"obj.array[1]=%@",obj.array[1]);
		
		
		obj.name = @"xx";
		NSLog(@"obj.name=%@",obj.name);
		NSLog(@"cop.name=%@",cop.name);
	}
	return 0;
}



三 总结

  • 若想令自己所写的对象具有拷贝功能,需要实现NSCopying 协议

  • 如果自定义的对象分为不可变版本与可变版本,那么就要同时是此案NSCopying 与NSMutableCopying协议

  • 复制对象时需决定采用浅拷贝还是深拷贝,一般情况下应该尽量执行浅拷贝

  • 如果你所写的对象需要深拷贝,那么可考虑新增一个专门执行深拷贝的方法


你可能感兴趣的:(ios,oc,NSCopying)