美文网首页
iOS 深拷贝和浅拷贝

iOS 深拷贝和浅拷贝

作者: 最是光阴化浮末 | 来源:发表于2018-08-04 15:40 被阅读65次

    浅拷贝就是拷贝后,并没有进行真正的复制,拷贝后的对象和原对象都指向同一块内存地址

    深拷贝是真正的复制了一份,复制的对象指向了新的内存地址

    浅拷贝就相当于自己的影子,而深拷贝则是克隆的你

    //注意
    //copy 在拷贝不可变对象的时候为浅拷贝,但是拷贝可变对象的时候为深拷贝
    //mutablecopy 始终为深拷贝
    

    copy

    NSLog(@"-----------------copy-----------------");
    //不可变对象
    NSString *str = @"字符串";
    NSString *copyStr = str.copy;
    NSLog(@"\n不可变字符串");
    NSLog(@"\nstr_p:%p,\ncopyStr_p:%p",str,copyStr);
    //    不可变字符串
    //    str_p:0x1043b72a8,
    //    copyStr_p:0x1043b72a8
    
    NSArray *array = [NSArray array];
    NSArray *copyArray = array.copy;
    NSLog(@"\n不可变数组");
    NSLog(@"\narray_p:%p,\ncopyArray_p:%p",array,copyArray);
    //    不可变数组
    //    array_p:0x6040000091f0,
    //    copyArray_p:0x6040000091f0
    
    //copy在拷贝不可变对象的时候为浅拷贝,浅拷贝的对象共用同一块内存地址
    
    
    
    //可变对象
    NSMutableString *mutablestr = [[NSMutableString alloc] initWithString:@"可变字符串"];
    NSString *copyMutablestr = mutablestr.copy;
    NSLog(@"\n可变字符串");
    NSLog(@"\nmutablestr_p:%p,\ncopyMutablestr_p:%p",mutablestr,copyMutablestr);
    //    可变字符串
    //    mutablestr_p:0x60000005a700,
    //    copyMutablestr_p:0x600000059c50
    
    NSMutableArray *mutableArray = [NSMutableArray arrayWithCapacity:0];
    NSArray *copyMutableArray = mutableArray.copy;//可变数组copy后,虽然为新的对象,但是对象类型是NSArray而不是NSMutableArray
    NSLog(@"\n可变数组");
    NSLog(@"\nmutableArray_p:%p,\ncopyMutableArray_p:%p",mutableArray,copyMutableArray);
    //    可变数组
    //    mutableArray_p:0x604000457a90,
    //    copyMutableArray_p:0x6040000091f0
    

    由此可得出结论
    copy在拷贝可变对象的时候为深拷贝,深拷贝的对象为全新的对象,有自己的内存地址
    拷贝不可变对象的时候为浅拷贝,浅拷贝的对象共用同一块内存地址

    mutablecopy

    NSLog(@"-----------------mutableCopy-----------------");
    NSString *str = @"字符串";
    NSString *mutableCopyStr = str.mutableCopy;
    NSLog(@"\n不可变字符串");
    NSLog(@"\nstr_p:%p,\nmutableCopyStr:%p",str,mutableCopyStr);
    //    不可变字符串
    //    str_p:0x10aa092c8,
    //    mutableCopyStr:0x600000041f20
    
    NSArray *array = [NSArray array];
    NSArray *mutablecopyArray = array.mutableCopy;
    NSLog(@"\n不可变数组");
    NSLog(@"\narray_p:%p,\nmutablecopyArray_p:%p",array,mutablecopyArray);
    //    不可变数组
    //    array_p:0x6000000034e0,
    //    mutablecopyArray_p:0x604000256980
    
    //可变对象
    NSMutableString *mutablestr = [[NSMutableString alloc] initWithString:@"可变字符串"];
    NSString *mutablecopyMutablestr = mutablestr.mutableCopy;
    NSLog(@"\n可变字符串");
    NSLog(@"\nmutablestr_p:%p,\nmutablecopyMutablestr_p:%p",mutablestr,mutablecopyMutablestr);
    //    可变字符串
    //    mutablestr_p:0x600000241f50,
    //    mutablecopyMutablestr_p:0x60000005f440
    
    
    NSMutableArray *mutableArray = [NSMutableArray arrayWithCapacity:0];
    NSArray *mutablecopyMutableArray = mutableArray.mutableCopy;//
    NSLog(@"\n可变数组");
    NSLog(@"\nmutableArray_p:%p,\nmutablecopyMutableArray_p:%p",mutableArray,mutablecopyMutableArray);
    //    可变数组
    //    mutableArray_p:0x604000255060,
    //    mutablecopyMutableArray_p:0x6040002555d0
    

    由此可得出结论:mutablecopy都是深拷贝,拷贝后的对象都有自己的内存地址

    当容器内有元素的时候,对对象的copy和mutablecopy会对里面的元素有啥影响呢?

    NSMutableArray *mutableArray = [NSMutableArray arrayWithObjects:[NSMutableString stringWithString:@"1"],@"2", nil];
    NSMutableArray *copyMutableArray = mutableArray.copy;
    NSMutableArray *mutableCopyMutableArray = mutableArray.mutableCopy;
    
    NSLog(@"mutableArray_p:%p,copyMutableArray_p:%p,mutableCopyMutableArray_p:%p",mutableArray,copyMutableArray,mutableCopyMutableArray);
    //mutableArray_p:0x60000025c0e0,
    //copyMutableArray_p:0x600000231980,
    //mutableCopyMutableArray_p:0x60000025e120
    
    //拷贝前
    NSLog(@"mutableArray_object1_p:%p,mutableArray_object2_p:%p",mutableArray[0],mutableArray[1]);
    //mutableArray_object1_p:0x60000025da90,
    //mutableArray_object2_p:0x10d9b34c8
    
    //copy后
    NSLog(@"copyMutableArray_object1_p:%p,copyMutableArray_object2_p:%p",copyMutableArray[0],copyMutableArray[1]);
    //copyMutableArray_object1_p:0x60000025da90,
    //copyMutableArray_object2_p:0x10d9b34c8
    
    //mutablecopy后
    NSLog(@"mutableCopyMutableArray_object1_p:%p,mutableCopyMutableArray_object2_p:%p",mutableCopyMutableArray[0],mutableCopyMutableArray[1]);
    //mutableCopyMutableArray_object1_p:0x60000025da90,
    //mutableCopyMutableArray_object2_p:0x10d9b34c8
    

    由此可见,copy和mutablecopy对于容器内的元素是浅拷贝

    如果你想对容器做完全拷贝(也就是容器深拷贝,元素也深拷贝)该怎么办呢?可以使用归档的办法(如果是自定义对象,需要实现NSCoding协议,不然会crash)。

    NSArray *array = [NSArray arrayWithObjects:[NSMutableString stringWithString:@"1"],@"2", nil];
    NSData *data = [NSKeyedArchiver archivedDataWithRootObject:array];
    NSArray *mutablecopyArray = [NSKeyedUnarchiver unarchiveObjectWithData:data];
    
    NSLog(@"array_p:%p,array_objec1_p:%p,array_objec2_p:%p",array,array[0],array[1]);
    //array_p:0x6040002386c0,
    //array_objec1_p:0x60400025f590,
    //array_objec2_p:0x10d17b4c8
    NSLog(@"mutablecopyArray_p:%p,mutablecopyArray_objec1_p:%p,mutablecopyArray_objec2_p:%p",mutablecopyArray,mutablecopyArray[0],mutablecopyArray[1]);
    //mutablecopyArray_p:0x604000238780,
    //mutablecopyArray_objec1_p:0x60400005ce60,
    //mutablecopyArray_objec2_p:0xa000000000000321
    

    自定义对象的归档协议实现

    #import "Student.h"
    @interface Student ()<NSCoding>
    @property (nonatomic,copy)NSString *age;
    @end
    @implementation Student
    
    /**********编码/解码***********/
    //解码的时候调用
    - (instancetype)initWithCoder:(NSCoder *)aDecoder
    {
        self.age = [aDecoder decodeObjectForKey:@"age"];
        return self;
    }
    //编码的时候调用
    - (void)encodeWithCoder:(NSCoder *)aCoder
    {
        [aCoder encodeObject:self.age forKey:@"age"];
    }
    @end
    

    自定义对象的copy和mutablecopy,需要实现NSCopying、NSMutableCopying协议,不然使用copy和mutablecopy方法会crash

    #import "Student.h"
    @interface Student ()<NSCopying,NSMutableCopying>
    @property (nonatomic,copy)NSString *age;
    @end
    @implementation Student
    
    /******浅拷贝/深拷贝*******/
    - (id)copyWithZone:(NSZone *)zone
    {
    
        Student *s = [[[self class] allocWithZone:zone] init];
        s.age = self.age;
        return s;
    }
    
    
    - (id)mutableCopyWithZone:(NSZone *)zone
    {
    
        Student *s = [[[self class] allocWithZone:zone] init];
        s.age = self.age;
        return s;
    }
    @end
    

    相关文章

      网友评论

          本文标题:iOS 深拷贝和浅拷贝

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