iOS 關(guān)于copy與mutableCopy淺析

君不見,高堂明鏡悲白發(fā),朝如青絲暮成雪

前記

最近在項目中,用到了關(guān)于copy的問題,當(dāng)我對自己定義的模型進(jìn)行拷貝的時候,居然沒有實現(xiàn)想要的深拷貝,于是出了點小問題,讓我有點小郁悶,所以決定好好深入研究下copymutableCopyNSDictionary、NSArray、model之間的小事~

copy 、mutableCopy

先來看看這兩個的區(qū)別吧

在分析區(qū)別之前,我們先上一段簡單的代碼

    //非集合類測試copy 和 mutablecopy
    NSString *string = @"abc";
    NSString *copyString = [string copy];
    //mutableCopy 后位動態(tài)string
    NSString *mutableCopyString = [string mutableCopy];
    
    NSString *mutableCopy_copy_String = [mutableCopyString copy];
    NSMutableString *mutableCopy_mutable_copy_String = [mutableCopyString mutableCopy];
    
    NSLog(@" 打印信息:%p---%p---%p---%p---%p",string,copyString,mutableCopyString,mutableCopy_copy_String,mutableCopy_mutable_copy_String);
    
    
    //集合類型測試copy 和 mutablecopy
    NSDictionary *_dic = @{@"key1":@"abc",@"key2":@"cde"};
    NSDictionary *copyDic = [_dic copy];

    NSMutableDictionary *mutableCopyDic = [_dic mutableCopy];
    [mutableCopyDic setValue:@"efg" forKey:@"key3"];
    
    NSMutableDictionary *mutableCopy_copy_Dic = [mutableCopyDic copy];
    NSMutableDictionary *mutableCopy_mutableCopy_Dic = [mutableCopyDic mutableCopy];
    
    NSLog(@" 打印信息字典拷貝:%p---%p---%p---%p---%p",_dic,copyDic,mutableCopyDic,mutableCopy_copy_Dic,mutableCopy_mutableCopy_Dic);
    
    
    //打印結(jié)果
    2017-08-17 15:06:33.277 GLDeepCopy[27242:8168435]  打印信息:0x10b30c0e8---0x10b30c0e8---0x608000074e00---0xa000000006362613---0x608000074e40    
    2017-08-17 15:06:33.278 GLDeepCopy[27242:8168435]  打印信息字典拷貝:0x600000072800---0x600000072800---0x60000005c8c0---0x600000072840---0x60000005cb30

順便插個圖片

copy.png
  • copy:對我們的對象進(jìn)行拷貝,返回一個非動態(tài)的對象
  • mutableCopy:對我們的對象進(jìn)行拷貝,返回一個動態(tài)的對象

通過上圖,我們可以看到,雖然我們用的是NSString來接收[string mutableCopy],但是實際上得到的卻是一個NSMutableString類型的對象,這里不得不說一個比較嚴(yán)重的問題,就是如果我們在定義一個動態(tài)類型為@property (nonatomic,copy)屬性后,一定不能執(zhí)行copy操作,否則在你執(zhí)行修改動態(tài)類型內(nèi)容的時候,一定會crash,因為當(dāng)你copy后,你的動態(tài)類型已經(jīng)變成了一個不可變類型

下面我們來看上面貼的代碼,從代碼分析,我們可以看到,非集合類型和集合類型中的非動態(tài)類型,在copy后,地址還是一樣的,沒有變化,而除此之外,地址都發(fā)生了變化,我們可以得到下面的結(jié)論

  • 非集合類型和集合類型非動態(tài)類型在copy后,執(zhí)行的是淺拷貝(即對指針進(jìn)行拷貝)
  • 非集合類型和集合類型非動態(tài)類型在mutableCopy后,執(zhí)行的是深拷貝(即對對象進(jìn)行拷貝),且返回動態(tài)類型
  • 非集合類型和集合類型動態(tài)類型在copy后,執(zhí)行的是深拷貝
  • 非集合類型和集合類型動態(tài)類型在mutableCopy后,執(zhí)行的是深拷貝,且返回動態(tài)類型

上面的結(jié)論也不是那么準(zhǔn)確,怎么說呢?容我慢慢分析

對于此處的深拷貝,我想大家一定想的是完完全全的拷貝吧,是的,我一開始也是這么想的,但是有沒有想過測試下,當(dāng)我們的集合有很多層的情況呢?下面就舉個例子來說明吧

代碼走起

@interface PersonModel : NSObject<NSCopying>

@property (nonatomic,copy) NSString *name;
@property (nonatomic,assign) NSUInteger age;

@end

@implementation PersonModel
- (id)copyWithZone:(NSZone *)zone{
    PersonModel *copy = [[PersonModel alloc] init];
    
    if (copy) {
        
        copy.name = [self.name copyWithZone:zone];
        copy.age = self.age;
        copy.array = [self.array copyWithZone:zone];
    }
    return copy;
}

@end



{
    //測試加入數(shù)組中  對數(shù)組進(jìn)行拷貝
    PersonModel *new_PersonModel = [[PersonModel alloc] init];
    new_PersonModel.name = @"gaogaogao";
    new_PersonModel.age = 20;
    
    NSLog(@" 打印信息修改后 personModel :%@\n new_PersonModel:%@",personModel,new_PersonModel);
    
    
    NSArray *array = [NSArray arrayWithObject:new_PersonModel];
    NSArray *copyArray = [array copy];
    NSMutableArray *mutableCopyArray = [array mutableCopy];
    
    NSLog(@" 打印信息array:%p+%@\ncopyArray:%p+%@\nmutableCopyArray:%p+%@",array,array,copyArray,copyArray,mutableCopyArray,mutableCopyArray);
    
    //修改數(shù)組中的內(nèi)容
    PersonModel *personModel_array = array[0];
    personModel_array.name = @"gao_array";
    personModel_array.age = 24;

    
    NSLog(@" 打印信息修改后array:%p+%@\ncopyArray:%p+%@\nmutableCopyArray:%p+%@",array,array,copyArray,copyArray,mutableCopyArray,mutableCopyArray);
    
}

//打印結(jié)果
2017-08-17 15:31:31.136 GLDeepCopy[27447:8197824]  打印信息array:0x608000017590+(
    "{\n    age = 20;\n    name = gaogaogao;\n}"
)
copyArray:0x608000017590+(
    "{\n    age = 20;\n    name = gaogaogao;\n}"
)
mutableCopyArray:0x608000243570+(
    "{\n    age = 20;\n    name = gaogaogao;\n}"
)
2017-08-17 15:31:31.164 GLDeepCopy[27447:8197824]  打印信息修改后array:0x608000017590+(
    "{\n    age = 24;\n    name = \"gao_array\";\n}"
)
copyArray:0x608000017590+(
    "{\n    age = 24;\n    name = \"gao_array\";\n}"
)
mutableCopyArray:0x608000243570+(
    "{\n    age = 24;\n    name = \"gao_array\";\n}"
)

從上面的打印信息中,我們看mutableCopyArray的地址,可以發(fā)現(xiàn),地址是發(fā)生了改變的,說明我們現(xiàn)在是執(zhí)行了深拷貝的,但是看打印信息修改后array這個位置,你會發(fā)現(xiàn),后面的內(nèi)容在修改后,居然變成一樣的了,但是我們明明修改的是array[0]中的對象的值啊,什么鬼??,是不是有點郁悶,那么下面我修改下打印信息,再來看看

 
 NSLog(@" 打印信息array:%p+%@ + %p\ncopyArray:%p+%@ + %p\nmutableCopyArray:%p+%@ + %p",array,array,array[0],copyArray,copyArray,copyArray[0],mutableCopyArray,mutableCopyArray,mutableCopyArray[0]);
 
 //打印信息
 2017-08-17 15:43:51.018 GLDeepCopy[27521:8211644]  打印信息array:0x6080000089f0+(
    "{\n    age = 20;\n    name = gaogaogao;\n}"
) + 0x6000000352e0
copyArray:0x6080000089f0+(
    "{\n    age = 20;\n    name = gaogaogao;\n}"
) + 0x6000000352e0
mutableCopyArray:0x60800005bdb0+(
    "{\n    age = 20;\n    name = gaogaogao;\n}"
) + 0x6000000352e0

是的,可以看到,三個數(shù)組里面的對象是同一個對象,也就是,數(shù)組雖然進(jìn)行了深拷貝,但是并沒有對里面的內(nèi)容進(jìn)行深拷貝,而是執(zhí)行的指針拷貝,瞬間有種懵逼的感覺,特么搞了這么久,還是不能執(zhí)行完全的深拷貝。所以,上面我們總結(jié)的4點中關(guān)于集合類型深拷貝不能算是真正意義上的深拷貝,只能說是一種單層的深拷貝,即至少有一層是執(zhí)行了深拷貝的,但是在實際中,我們往往需要的是完完全全的完全深拷貝,那么針對集合類型,我們又該怎么來實現(xiàn)完全深拷貝呢?

集合的完全深拷貝

關(guān)于集合的完全深拷貝,這里有兩種方法

  • 通過歸檔的方式來實現(xiàn)(后面會講到)
  • 通過使用集合自帶的方法來實現(xiàn)(并不完美)

先來講講 這個并不完美的方法吧

以上面的例子來將,我們可以使用NSArray中的

- (instancetype)initWithArray:(NSArray<ObjectType> *)array copyItems:(BOOL)flag;

當(dāng)flag參數(shù)設(shè)置為YES的時候,集合里的每個對象都會去執(zhí)行copyWithZone方法,當(dāng)然這就必須要求我們的對象必須遵循 NSCopying協(xié)議,并且實現(xiàn)copyWithZone方法,此時對象就會被深復(fù)制到新的集合。如果對象沒有遵循 NSCopying 協(xié)議,而用這種方法進(jìn)行深拷貝,就會在運行時出錯

來實現(xiàn),當(dāng)然NSDictionaryNSSet也有對應(yīng)的方法

- (instancetype)initWithDictionary:(NSDictionary<KeyType, ObjectType> *)otherDictionary copyItems:(BOOL)flag;
- (instancetype)initWithSet:(NSSet<ObjectType> *)set copyItems:(BOOL)flag;

先看修改后的

{
  //測試加入數(shù)組中  對數(shù)組進(jìn)行拷貝
    PersonModel *new_PersonModel = [[PersonModel alloc] init];
    new_PersonModel.name = @"gaogaogao";
    new_PersonModel.age = 20;
    
    NSLog(@" 打印信息修改后 personModel :%@\n new_PersonModel:%@",personModel,new_PersonModel);
    
    
    NSArray *array = [NSArray arrayWithObject:new_PersonModel];
    NSArray *copyArray = [array copy];
    NSMutableArray *mutableCopyArray = [[NSMutableArray alloc] initWithArray:array copyItems:YES];//[array mutableCopy];
    
    NSLog(@" 打印信息array:%p+%@ + %p\ncopyArray:%p+%@ + %p\nmutableCopyArray:%p+%@ + %p",array,array,array[0],copyArray,copyArray,copyArray[0],mutableCopyArray,mutableCopyArray,mutableCopyArray[0]);
    
    //修改數(shù)組中的內(nèi)容
    PersonModel *personModel_array = array[0];
    personModel_array.name = @"gao_array";
    personModel_array.age = 24;

    NSLog(@" 打印信息修改后array:%p+%@\ncopyArray:%p+%@\nmutableCopyArray:%p+%@",array,array,copyArray,copyArray,mutableCopyArray,mutableCopyArray);

}

//打印結(jié)果
2017-08-17 16:03:48.954 GLDeepCopy[27694:8234722]  打印信息array:0x6080000030f0+(
    "{\n    age = 20;\n    name = gaogaogao;\n}"
) + 0x6080000284c0
copyArray:0x6080000030f0+(
    "{\n    age = 20;\n    name = gaogaogao;\n}"
) + 0x6080000284c0
mutableCopyArray:0x60800004cae0+(
    "{\n    age = 20;\n    name = gaogaogao;\n}"
) + 0x608000028420
2017-08-17 16:03:48.955 GLDeepCopy[27694:8234722]  打印信息修改后array:0x6080000030f0+(
    "{\n    age = 24;\n    name = \"gao_array\";\n}"
)
copyArray:0x6080000030f0+(
    "{\n    age = 24;\n    name = \"gao_array\";\n}"
)
mutableCopyArray:0x60800004cae0+(
    "{\n    age = 20;\n    name = gaogaogao;\n}"
)

從上面的結(jié)果,我們可以看出,最終實現(xiàn)了我們想要的效果,對數(shù)組實現(xiàn)了完全深拷貝,從這里看上去,還是挺完美的嘛,然而在實際中,你知道的,肯定不止這么多層,下面我們再改造下,在PersonModel中增加一個array,并且新增一個類Anima

@interface Anima : NSObject<NSCopying>

@property (nonatomic,copy) NSString *address;

@end

@implementation Anima

- (id)copyWithZone:(NSZone *)zone{
    Anima *copy = [[Anima alloc] init];
    
    if (copy) {
        
        copy.address = [self.address copyWithZone:zone];
    }
    return copy;
}


@end

@interface PersonModel : NSObject<NSCopying,NSMutableCopying>

@property (nonatomic,copy) NSString *name;
@property (nonatomic,assign) NSUInteger age;

@property (nonatomic,strong) NSMutableArray *array;

@end
.
.
.

//實現(xiàn)部分
    //測試加入數(shù)組中  對數(shù)組進(jìn)行拷貝
    PersonModel *new_PersonModel = [[PersonModel alloc] init];
    new_PersonModel.name = @"gaogaogao";
    new_PersonModel.age = 20;
    Anima *anima = [[Anima alloc] init];
    anima.address = @"成都";
    new_PersonModel.array = [NSMutableArray arrayWithObject:anima];
        
    NSArray *array = [NSArray arrayWithObject:new_PersonModel];
    NSArray *copyArray = [array copy];
    NSMutableArray *mutableCopyArray = [[NSMutableArray alloc] initWithArray:array copyItems:YES];//[array mutableCopy];//
    
    NSLog(@" 打印信息array:%p+%@ + %p\ncopyArray:%p+%@ + %p\nmutableCopyArray:%p+%@ + %p",array,array,array[0],copyArray,copyArray,copyArray[0],mutableCopyArray,mutableCopyArray,mutableCopyArray[0]);
    
    
    
    //修改數(shù)組中的內(nèi)容
    PersonModel *personModel_array = array[0];
    personModel_array.name = @"gao_修改";
    personModel_array.age = 24;
    
    Anima *anima_model = personModel_array.array[0];
    anima_model.address = @"閬中";
    
    //獲取深拷貝數(shù)組中的model中數(shù)組中的model
    PersonModel *personModel_mutable_copy_array = mutableCopyArray[0];
    Anima *anima_model_mutable_copy = personModel_mutable_copy_array.array[0];
    
    NSLog(@" 打印信息獲取深拷貝數(shù)組中的model中數(shù)組中的model地址:%p ++ %p",anima_model,anima_model_mutable_copy);
    
    
    NSLog(@" 打印信息修改后array:%p+%@\ncopyArray:%p+%@\nmutableCopyArray:%p+%@",array,array,copyArray,copyArray,mutableCopyArray,mutableCopyArray);
    
    //打印信息 截取部分說明
    2017-08-18 15:27:32.324 GLDeepCopy[69373:9095757]  打印信息獲取深拷貝數(shù)組中的model中數(shù)組中的model地址:0x608000013100 ++ 0x608000013100

從上面的結(jié)果分析,當(dāng)層次一多,該方法也并不能完成我們想要的完全拷貝,那么我們除了用歸檔的方式,難道就沒有其他方式了么?答案肯定是 還有的,可以這么設(shè)想一下,集合無外乎就是裝了很多東西,既然是這樣,我們何必不針對集合里面的內(nèi)容層層進(jìn)行深拷貝呢?是的,我們可以通過遍歷的方式來進(jìn)行,為了方便使用,可以新建一個Category,于是乎就有了下面的代碼,我們先以NSArray為例

#import <Foundation/Foundation.h>

@interface NSArray (GLDeepCopy)


/**
 返回當(dāng)前類型

 @return 返回
 */
- (instancetype)GLDeepCopy;

@end


#import "NSArray+GLDeepCopy.h"

@implementation NSArray (GLDeepCopy)

- (instancetype)GLDeepCopy
{
    NSMutableArray *resultMutableArray = [[NSMutableArray alloc] initWithCapacity:self.count];
    
    for (id object in self) {
        
        //定義一個id類型來接收拷貝后的
        id copyObject = nil;
        
        //如果該對象有該方法 
        if ([object respondsToSelector:@selector(GLDeepCopy)]) {
            copyObject = [object GLDeepCopy];
        //判斷該對象是否實現(xiàn)了NSCopying 協(xié)議的方法  如果是 則進(jìn)行copy
        }else if ([object conformsToProtocol:@protocol(NSCopying)]){
            copyObject = [object copy];
        }else if ([object conformsToProtocol:@protocol(NSMutableCopying)]){
            copyObject = [object mutableCopy];
        }else{
            copyObject = object;
        }
        
        [resultMutableArray addObject:copyObject];
    }
    
    if ([self isKindOfClass:[NSArray class]]) {
        return [NSArray arrayWithArray:resultMutableArray];
    }else{
        return resultMutableArray;
    }
}

@end

在上面方法中,我們通過遍歷數(shù)組中的內(nèi)容來進(jìn)行循環(huán)拷貝,[object respondsToSelector:@selector(GLDeepCopy)],這一句是如果我們的對象實現(xiàn)了該方法,我們就去調(diào)用,比如當(dāng)前對象是數(shù)組,字典,NSSet或者是自定義數(shù)據(jù)模型,針對自定義數(shù)據(jù)模型,如果包含集合類型,而且又需要進(jìn)行完全拷貝的時候,最好實現(xiàn)GLDeepCopy方法,后面有例子。如果沒有集合類型,但是需要完全拷貝的話,就可以通過實現(xiàn)NSCopying或者NSMutableCopying協(xié)議來實現(xiàn)。

#import <Foundation/Foundation.h>

@interface PersonModel : NSObject<NSCopying,NSMutableCopying>

@property (nonatomic,copy) NSString *name;
@property (nonatomic,assign) NSUInteger age;

@property (nonatomic,strong) NSMutableArray *array;

@end

#import "PersonModel.h"
#import "NSArray+GLDeepCopy.h"
#import <objc/runtime.h>

@interface PersonModel()


@end

@implementation PersonModel


/**
 描述信息
 
 @return 返回描述信息  利于我們在debug 的時候方便查看
 */
- (NSString *)description
{
    return [NSString stringWithFormat:@"%@",[self getObjectData:self]];
}


#pragma mark == Copying協(xié)議
- (id)copyWithZone:(NSZone *)zone{
    PersonModel *copy = [[PersonModel alloc] init];
    
    if (copy) {
        
        copy.name = [self.name copyWithZone:zone];
        copy.age = self.age;
        copy.array = [self.array copyWithZone:zone];
    }
    return copy;
}

- (id)mutableCopyWithZone:(NSZone *)zone
{
    PersonModel *copy = [[PersonModel alloc] init];
    
    if (copy) {
        
        copy.name = [self.name mutableCopyWithZone:zone];
        copy.age = self.age;
        copy.array = [self.array mutableCopyWithZone:zone];
    }
    return copy;
}


#pragma mark == 深拷貝 
//(如果沒有集合類型,可以不用執(zhí)行)
- (id)GLDeepCopy
{
    PersonModel *personModel = [[PersonModel alloc] init];
    personModel.age = self.age;
    personModel.name = [self.name copy];
    personModel.array = [self.array GLDeepCopy];
    
    return personModel;
}

#pragma mark == 轉(zhuǎn)換

/**
 將對象轉(zhuǎn)為NSDictionary
 
 @param obj 對象
 @return 返回的NSDictionary
 */
- (NSDictionary*)getObjectData:(id)obj
{
    NSMutableDictionary *dic = [NSMutableDictionary dictionary];
    unsigned int propsCount;
    objc_property_t *props = class_copyPropertyList([obj class], &propsCount);
    for(int i = 0;i < propsCount; i++)
    {
        objc_property_t prop = props[i];
        
        NSString *propName = [NSString stringWithUTF8String:property_getName(prop)];
        id value = [obj valueForKey:propName];
        if(value == nil)
        {
            value = [NSNull null];
        }
        else
        {
            value = [self getObjectInternal:value];
        }
        
        [dic setObject:value forKey:propName];
    }
    return dic;
}


/**
 針對對象里面屬性的不同屬性 進(jìn)行轉(zhuǎn)換
 
 @param obj 對象
 @return 返回
 */
- (id)getObjectInternal:(id)obj
{
    if([obj isKindOfClass:[NSString class]]
       || [obj isKindOfClass:[NSNumber class]]
       || [obj isKindOfClass:[NSNull class]])
    {
        return obj;
    }
    
    if([obj isKindOfClass:[NSArray class]])
    {
        NSArray *objarr = obj;
        NSMutableArray *arr = [NSMutableArray arrayWithCapacity:objarr.count];
        for(int i = 0;i < objarr.count; i++)
        {
            [arr setObject:[self getObjectInternal:[objarr objectAtIndex:i]] atIndexedSubscript:i];
        }
        return arr;
    }
    
    if([obj isKindOfClass:[NSDictionary class]])
    {
        NSDictionary *objdic = obj;
        NSMutableDictionary *dic = [NSMutableDictionary dictionaryWithCapacity:[objdic count]];
        for(NSString *key in objdic.allKeys)
        {
            [dic setObject:[self getObjectInternal:[objdic objectForKey:key]] forKey:key];
        }
        return dic;
    }
    return [self getObjectData:obj];
}

在上面的自定義模型中,我們包含NSMutableArray,而且我們希望實現(xiàn)完全拷貝,所以實現(xiàn)了GLDeepCopy,并且針對其中的NSMutableArray調(diào)用了Category中的 GLDeepCopy方法,在看另一個模型

#import <Foundation/Foundation.h>

@interface Anima : NSObject<NSCopying>

@property (nonatomic,copy) NSString *address;

@end


#import "Anima.h"

@interface Anima ()



@end

@implementation Anima

- (id)copyWithZone:(NSZone *)zone{
    Anima *copy = [[Anima alloc] init];
    
    if (copy) {
        copy.address = [self.address copyWithZone:zone];
    }
    return copy;
}


@end

由于該模型,沒有包含集合類型,所以我只是簡單的實現(xiàn)了NSCopying協(xié)議,下面來看使用情況

    //測試加入數(shù)組中  對數(shù)組進(jìn)行拷貝
    PersonModel *new_PersonModel = [[PersonModel alloc] init];
    new_PersonModel.name = @"gaogaogao";
    new_PersonModel.age = 20;
    Anima *anima = [[Anima alloc] init];
    anima.address = @"成都";
    new_PersonModel.array = [NSMutableArray arrayWithObject:anima];
    [new_PersonModel.array addObject:@[@"1",@"2",@"3"]];
    
        
    NSArray *array = [NSArray arrayWithObject:new_PersonModel];
    NSArray *copyArray = [array copy];
    NSMutableArray *mutableCopyArray = [NSMutableArray arrayWithArray:[array GLDeepCopy]];//[[NSMutableArray alloc] initWithArray:array copyItems:YES];//[array mutableCopy];//
    
    NSLog(@" 打印信息array:%p+%@ + %p\ncopyArray:%p+%@ + %p\nmutableCopyArray:%p+%@ + %p",array,array,array[0],copyArray,copyArray,copyArray[0],mutableCopyArray,mutableCopyArray,mutableCopyArray[0]);
    
    
    
    //修改數(shù)組中的內(nèi)容
    PersonModel *personModel_array = array[0];
    personModel_array.name = @"gao_修改";
    personModel_array.age = 24;
    
    Anima *anima_model = personModel_array.array[0];
    anima_model.address = @"閬中";
    
    //獲取深拷貝數(shù)組中的model中數(shù)組中的model
    PersonModel *personModel_mutable_copy_array = mutableCopyArray[0];
    Anima *anima_model_mutable_copy = personModel_mutable_copy_array.array[0];
    
    NSLog(@" 打印信息獲取深拷貝數(shù)組中的model中數(shù)組中的model地址:\n原數(shù)組中的PersonModel中Array中的Anima:%p \n 原數(shù)組中的PersonModel中Array中的非Anima對象%p\n++ 深拷貝數(shù)組中的PersonModel中Array中的Anima:%p \n 深拷貝數(shù)組中的PersonModel:%p \n+ 深拷貝數(shù)組中的PersonModel中Array中的非Anima對象%p",anima_model,personModel_array.array[1],anima_model_mutable_copy,personModel_mutable_copy_array,personModel_mutable_copy_array.array[1]);
    
    
    NSLog(@" 打印信息修改后array:%p+%@\ncopyArray:%p+%@\nmutableCopyArray:%p+%@",array,array,copyArray,copyArray,mutableCopyArray,mutableCopyArray);
    

打印信息

完全拷貝.png

打印信息的排版有點亂,這不是重點,通過觀察,我們可以發(fā)現(xiàn)數(shù)組中模型中的數(shù)組中的模型都是進(jìn)行了完全拷貝,看最后一行打印信息,前面兩個數(shù)組中的address都和第一行中的不一樣,因為我們把地址改成了閬中,而最后一個數(shù)組中的address卻還保持著之前的值,這說明,我們是完成了完全拷貝的

上面我用的是NSArray進(jìn)行的舉例,而其他集合類型NSDictionaryNSSetCategory方法也大同小異

相關(guān)代碼,請移步demo如果覺得還可以,可以給個star哦,不甚感激~

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容