iOS-深浅拷贝

首先关于copy和mutableCopy的行为:无论是NSString这种元素类、仍是NSArray这样的容器类、仍是Mutable和非Mutable类,copy和mutableCopy调用后表现的行为究竟是什么样完成取决于类自己NSCopying和NSMutableCopying协议是如何实现的。数组

想要正常调用copy和mutableCopy两个函数,那么类就必定要实现对应的协议。函数

1.  元素数据的copy和mutableCopy。spa

经常使用的NSString类,示例代码以下:.net

NSString* string = @”a”;
NSString* stringCopy = [string copy];// stringCopy与string地址相同,retainCount+ 1
NSMutableString* stringMCopy = [string mutablecopy];// stringMCopy与string地址不一样
 
NSMutableString* stringM1 = [stringMCopy copy];//地址与stringMCopy不一样,且为不可修改
NSMutableString* stringM2 = [stringMCopy mutablecopy];//地址与stringMCopy不一样,可修改 

 

能够基本推出NSString和NSMutableString中两个协议的实现指针

 

NSString:
- (id)copywithZone:(NSZone*)zone
{
  return self;
}
 
- (id)mutableCopywithZone:(NSZone*)zone
{
  NSMutableString* copy =[[NSMutableString alloc] initxxxxxx];
  ....
  return copy;
}
NSMutableString:
- (id)copywithZone:(NSZone*)zone
{
  NSString* copy = [[NSStringalloc] initxxxxxx];
  ....
  return copy;//因此不可修改
}
 
- (id)mutableCopywithZone:(NSZone*)zone
{
  NSMutableString* copy =[[NSMutableString alloc] initxxxxxx];
  ....
  return copy;
}

 

2.   容器类的copy和mutableCopy。code

经常使用类NSArray和NSMutableArray,看以下示例代码:对象

Class1* obj1= ....;//正常初始化
NSArray* array = [[NSArray alloc] initWithObjects:obj1, nil];
NSArray* arrayCopy = [array copy];//地址不变,retaincount+1
NSMutableArray* arrayMCopy = [array mutableCopy];//地址改变,可是数组中成员指针和obj1相同,浅拷贝

NSMutableArray* arrayM1 = [arrayMCopy Copy];//地址改变,可是数组中成员指针和obj1相同,浅拷贝。arrayM1为NSArray不可修改
NSMutableArray* arrayM2 = [arrayMCopy mutableCopy];//地址改变,可是数组中成员指针和obj1相同,浅拷贝

 

//推断  blog

NSArray:
- (id)copywithZone:(NSZone*)zone
{
  //伪码
  return [self retain];
}

- (id)mutableCopywithZone:(NSZone*)zone
{
  NSMutableArray* copy = [[NSMutableString alloc] initxxxxxx];
  for (id element in self) {
    [copy addObject:element];//element retian count + 1
    ....
  }
  return copy;
}

NSMutableArray:
- (id)copywithZone:(NSZone*)zone
{
  NSArray* copy = [[NSArray alloc] initXXX];
  /*把每一个element加入到copy数组,retainCount+1*/
  ....
  return copy;
}

- (id)mutableCopywithZone:(NSZone*)zone
{
  NSMutableArray* copy = [[NSMutableString alloc] initxxxxxx];
  for (id element in self) {
    [copy addObject:element];//element retian count + 1
    ....
  }
  return copy;
}

 

3.   深拷贝内存

上面提到的官方文档中介绍两种实现深拷贝的方法:ci

a.      用Array的initWithArray:  copyItems函数,以下:

NSArray *deepCopyArray=[[NSArray alloc] initWithArray: someArraycopyItems: YES];

调用后,会对原NSArray中的每一个元素调用其copy函数,并把返回的id加入到新的数组中。因此这是依赖于Obj对象类实现的深拷贝,若是- (id)copywithZone:(NSZone*)zone是从新分配一块内存赋值后返回,那么就是真正的深拷贝。若是直接返回自身,那么它只是浅拷贝。

b.      用archiver方式:

NSArray* trueDeepCopyArray = [NSKeyedUnarchiverunarchiveObjectWithData: [NSKeyedArchiver archivedDataWithRootObject:oldArray]];

这是真正意义上的深拷贝,不依赖于实际类Copying协议的实现。

 

4. 用Category实现自定义的深拷贝deepmutableCopy,如:

 

- (NSMutableArray *)mutableDeepCopy
{
    NSMutableArray *ret = [[NSMutableArrayalloc] initWithCapacity:[self count]];
    for (id value in self)
    {
        id oneCopy = nil;
        if ([value respondsToSelector:@selector(mutableDeepCopy)])
            oneCopy = [value mutableDeepCopy];
        else if ([value respondsToSelector:@selector(mutableCopy)])
            oneCopy = [value mutableCopy];
        if (oneCopy == nil)
            oneCopy = [value copy];
        [ret addObject: oneCopy];
    }
    return ret;
}

 

 

原文地址:http://blog.csdn.net/omegayy/article/details/7311839

相关文章
相关标签/搜索