美文网首页
数组深复制浅复制(方便阅读)

数组深复制浅复制(方便阅读)

作者: ZZ_军哥 | 来源:发表于2022-09-08 14:23 被阅读0次

一:数组的copy和mutableCopy:

@interface GYJTest : NSObject
@property(nonatomic,copy)NSString *str;
@property(nonatomic,assign)int age;
@end
@implementation GYJTest
@end
- (void)viewDidLoad{
    GYJTest *test = [[GYJTest alloc]init];
    test.str = [NSString stringWithFormat:@"%ld",1837891291834223121];
    test.age=10;
    NSArray*arr2 =@[test];
    NSArray*arr3 = arr2.copy;
    NSArray*arr4 = arr2.mutableCopy;
    NSLog(@"%p",test);
    NSLog(@"%p",arr2);
    NSLog(@"%p",arr3);
    NSLog(@"%p",arr4);
    NSLog(@"%p",arr3[0]);
    NSLog(@"%p",arr4[0]);
}
image

打印结果:

image

结论:

1.单纯的数组copy,只是指针复制,对其中一个数组进行修改,另一个也会跟着变动

2.数组的mutableCopy,属于深复制,会开辟数组的堆空间,但是仅限容器的复制,而容器内存储的指针数值保持不动,如果对元素的内容进行修改,两个数组内容都会跟着变动

二:那么如果要保证数组内容的完整的复制,包括数组元素的深复制,有两种方式

A.调用[[NSMutableArray alloc]initWithArray:arr copyItems:YES]函数进行复制,该函数会继续调用元素的NSCopying协议的- (id)copyWithZone:(nullable NSZone *)zone方法,人为的修改元素的复制内容,以达到深复制的目的,元素CCModel的copying协议按NSMutableCopying方式写,然后CCModel的嵌套层按正常的NSMutableCopying写,如下:


@interface CCModel : NSObject<NSCopying>
@property(nonatomic,assign)int count;
@property(nonatomic,strong)Person *per;
@end
@interface Person : NSObject<NSMutableCopying>
@property(nonatomic,copy)NSString *name;
@property(nonatomic,strong)Student *stu;
@end
@interface Student : NSObject<NSMutableCopying>
@property(nonatomic,assign)int score;
@property(nonatomic,copy)NSString *numString;
@end
@implementation CCModel
- (id)copyWithZone:(nullable NSZone *)zone{
    CCModel *model = [[CCModel alloc]init];
    model.count=self.count;
    model.per = self.per.mutableCopy;
    return  model;
}
@end
@implementation Person
- (id)mutableCopyWithZone:(nullable NSZone *)zone{
    Person *model = [[Person alloc]init];
    model.name = self.name.mutableCopy;
    model.stu = self.stu.mutableCopy;
    return  model;
}
@end
@implementation Student
- (id)mutableCopyWithZone:(nullable NSZone *)zone{
    Student *model = [[Student alloc]init];
    model.score=self.score;
    model.numString = self.numString.mutableCopy;
    return  model;
}
@end

验证代码:

    Student *stu = [[Student alloc]init];
    stu.score=90;
    stu.numString = @"2030221134";

    Person *per = [[Person alloc]init];
    per.name=@"tom";
    per.stu= stu;

    CCModel *model = [[CCModel alloc]init];
    model.per= per;
    model.count=1;
    NSArray*arr =@[model];

    NSMutableArray *arr1 = [[NSMutableArray alloc]initWithArray:arr copyItems:YES];
    NSLog(@"ccmodel:%p",model);
    NSLog(@"ccmodel.per:%p",model.per);
    NSLog(@"ccmodel.per.stu:%p",model.per.stu);
    CCModel*copyModel = arr1.firstObject;
    NSLog(@"copyModel:%p",copyModel);
    NSLog(@"copyModel.per:%p",copyModel.per);
    NSLog(@"copyModel.per.stu:%p",copyModel.per.stu);

打印效果:

image

从结果标明,通过这种方式可以达到对元素的深复制效果,就是需要注意CCModel对象以后可别调用model.copy,那可是完全的深复制,完全是两个对象了.

B.第二种方式,序列化操作通过实现NSCoding协议,调用序列化方法,深复制一个内容出来

NSArray*arr =@[model];
NSData *data = [NSKeyedArchiver archivedDataWithRootObject:arr];
NSArray *deepCopyArr = [NSKeyedUnarchiver unarchiveObjectWithData:data];

写法:

@interface CCModel : NSObject<NSCoding>
@property(nonatomic,assign)int count;
@property(nonatomic,strong)Person *per;
@end

@interface Person : NSObject<NSCoding>
@property(nonatomic,copy)NSString *name;
@property(nonatomic,strong)Student *stu;
@end

@interface Student : NSObject<NSCoding>
@property(nonatomic,assign)int score;
@property(nonatomic,copy)NSString *numString;
@end

#import  "CCModel.h"
#import <objc/runtime.h>

void encodeWithCoder(NSCoder *coder,id instance){
    unsigned int count =0;
    Ivar *ivars =class_copyIvarList([instance class], &count);
    for(int i = 0; i < count; i++){
        Ivar ivar = ivars[i];
        const char *cKey = ivar_getName(ivar);
        NSString *key = [NSString stringWithCString:cKey encoding:NSUTF8StringEncoding];
        id value = [instance valueForKey:key];
        [coder encodeObject:value forKey:key];
    }
    free(ivars);
}
void createInstanceByCoder(NSCoder *coder,id instance){
    unsigned int count =0;
    Ivar*ivars = class_copyIvarList([instance class], &count);
    for(int i = 0; i < count; i++){
        Ivar ivar = ivars[i];
        const char*cKey = ivar_getName(ivar);
        NSString *key = [NSString stringWithCString:cKey encoding:NSUTF8StringEncoding];
        id value = [coder decodeObjectForKey:key];
        [instance setValue:value forKey:key];
    }
    free(ivars);
}
@implementation CCModel
- (void)encodeWithCoder:(NSCoder *)coder{
    encodeWithCoder(coder,self);
}
- (instancetype)initWithCoder:(NSCoder *)coder{
    if (self = [super init]){
        createInstanceByCoder(coder,self);
    }
    return self;
}
@end
@implementation Person
- (void)encodeWithCoder:(NSCoder *)coder{
    encodeWithCoder(coder,self);
}
- (instancetype)initWithCoder:(NSCoder *)coder{
    if (self = [super init]){
        createInstanceByCoder(coder,self);
    }
    return self;
}
@end
@implementation Student
- (void)encodeWithCoder:(NSCoder *)coder{
    encodeWithCoder(coder,self);
}
- (instancetype)initWithCoder:(NSCoder *)coder{
    if (self = [super init]){
        createInstanceByCoder(coder,self);
    }
    return self;
}
@end

验证效果


   Student *stu = [[Student alloc]init];
    stu.score=90;
    stu.numString = @"2030221134";

    Person *per = [[Person alloc]init];
    per.name=@"tom";
    per.stu= stu;

    CCModel *model = [[CCModel alloc]init];
    model.per= per;
    model.count=1;

    NSArray*arr =@[model];
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:arr];
    NSArray *deepCopyArr = [NSKeyedUnarchiver unarchiveObjectWithData:data];
    NSLog(@"ccmodel:%p",model);
    NSLog(@"ccmodel.per:%p",model.per);
    NSLog(@"ccmodel.per.stu:%p",model.per.stu);

    CCModel*copyModel = deepCopyArr.firstObject;
    NSLog(@"copyModel:%p",copyModel);
    NSLog(@"copyModel.per:%p",copyModel.per);
    NSLog(@"copyModel.per.stu:%p",copyModel.per.stu);

打印结果显示:数组元素及元素嵌套的内容都不是同一个对象,达到了深复制的目的

image

相关文章

  • 数组深复制浅复制(方便阅读)

    一:数组的copy和mutableCopy: 打印结果: 结论: 1.单纯的数组copy,只是指针复制,对其中一个...

  • javascript 数组以及对象的深拷贝

    数组的深拷贝在js中,数组和对象的复制如果使用=号来进行复制,那只是浅拷贝。如下图演示: for 循环实现数组的深...

  • Javascript对象的深浅拷贝

    开门见山,有人叫对象的复制为深复制浅复制,也有人叫深拷贝浅拷贝。其实都是copy。 深拷贝(递归复制,复制所有层级...

  • 浅|深 复制

    浅复制 //只写main函数 //结果是 我们可以看到一旦pointArray1发生了改变pointArray2也...

  • 浅拷贝与深拷贝

    由于引用类型直接复制的效果是地址的复制,只是两个变量指向了同一块内存。 所以有了浅拷贝和深拷贝。 浅拷贝 数组的浅...

  • JS深浅拷贝

    浅拷贝 浅拷贝的意思就是只复制引用,而未复制真正的值。 深拷贝 深拷贝就是对目标的完全拷贝,不像浅拷贝那样只是复制...

  • Object-C关键字

    作为自己以后的一个备忘录,方便以后的查阅 含义: copy 复制内容(深复制),如果调用copy的是数组,则为指针...

  • OC属性常用关键字

    含义: copy 复制内容(深复制),如果调用copy的是数组,则为指针复制(浅复制),仅仅复制子元素的指针。 @...

  • 浅析iOS的浅复制与深复制

    原文:浅析iOS的浅复制与深复制 最近同事问我一个问题:原数组A,进行复制得到数组B,改变数组B的Person元素...

  • 深拷贝和浅拷贝

    深拷贝:复制多层 浅拷贝:复制一层 在JavaScript使用过程中我们经常会遇到这样的场景; 我们发现,当数组b...

网友评论

      本文标题:数组深复制浅复制(方便阅读)

      本文链接:https://www.haomeiwen.com/subject/gglonrtx.html