【学习ios之路:Objective-C】深拷贝和浅拷贝

深浅拷贝的区别:

       深拷贝   拷贝  内容

       浅拷贝  拷贝  地址

注:当对象str1在常量区时

①对不可变字符串NSString对象进行copy

        NSString *str1 = @"Hello"; //str1 -- 常量区
        NSLog(@"%p", str1);//0x100002048
        //copy
        NSString *str2 = [str1 copy];//0x100002048 str2 -- 常量区
        NSLog(@"%p", str2);//str2 与 str1都指向常量区,地址相同,引用计数为无穷大
        NSLog(@"str2 retaincount = %lu", [str2 retainCount]);<span style="font-size:18px;">//18446744073709551615</span>
②对不可变字符串NSString对象进行mutableCopy

        //mutableCopy,深拷贝,拷贝内容,而且拷贝出来的是一个可变的对象
        NSMutableString *str3 = [str1 mutableCopy];
        NSLog(@"str3 retaincount = %lu", [str3 retainCount]);//1
        [str3 appendString:@"world"];//对拷贝出来的对象进行操作
        NSLog(@"str3 = %@", str3);
注:当对象str1在堆区

        NSString *str1 = [NSString stringWithFormat:@"Frank"];
        NSLog(@"str1 = %p, retaincount = %lu", str1, [str1 retainCount]);//1
①对不可变字符串NSString对象进行copy

        //copy, 浅拷贝, 拷贝 地址, 并且将原有对象的引用计数加1.
        NSString *str2 = [str1 copy];// str2与str1指向同一块堆区空间
        NSLog(@"str2 = %p, retaincount = %lu", str2, [str2 retainCount]);//2
②对不可变字符串NSString对象进行mutableCopy
        //mutableCopy,深拷贝,拷贝内容,堆区开辟新的空间,并且拷贝出来的对象是可变的.
        NSMutableString *str3 = [str1 mutableCopy];//str3与str1指向不同的对象
        [str3 appendString:@"lanou"];
        NSLog(@"str3 = %p, retaincount = %lu", str3, [str3 retainCount]);//1
可变字符串(NSMutableString)
①对一个可变字符串NSMutableString对象copy
        //原有对象str1在堆区
        NSMutableString *str1 = [[NSMutableString alloc] initWithFormat:@"Frank"];
        NSLog(@"str1 = %p", str1);//0x10010b800
        //copy 堆区中开辟新的空间,拷贝内容到新的空间上,但是拷贝出来的是不可变字符串对象.
        NSString *str2 = [str1 copy];
        NSLog(@"str2 = %p, retaincount = %lu", str2, [str2 retainCount]);//1
②对一个可变字符串NSMutableString对象mutableCopy

        //mutableCopy 堆区中开辟新的空间,拷贝内容到新的空间上,但是拷贝出来的是可变字符串对象.
        NSMutableString *str3 = [str1 mutableCopy];
        [str3 appendString:@"lanou"];
        NSLog(@"str3 = %p, retaincount = %lu", str3, [str3 retainCount]);
总结:

        /**
         *  总结:拷贝是分为可变对象与不可变对象.
            浅拷贝 ---  只拷贝对象地址,不会拷贝内容,不会开辟新的空间.
            深拷贝 ---  拷贝内容,堆区开辟新的空间.
            不可变对象: 1.copy 相当于retin, 原有对象引用计数加1,拷贝地址.
                     2.mutableCopy 复制出新的对象,并且对象是可变的,开呗内容.
            可变对象: 1.copy 复制出新的对象,但是对象是不可变的,拷贝内容.
                     2.mutableCopy 复制出新的对象,但是对象是可变的,拷贝内容.
         */
③.对一个自定义对象Copy和mutableCopy,需要服从<NSCopying, NSMutableCopying>协议,例如:

1.创建Person.h

@interface Person : NSObject <NSCopying, NSMutableCopying>
@property (nonatomic, copy) NSString *name; //姓名
@property (nonatomic, copy) NSString *gender; //性别
@property (nonatomic) NSInteger age;//年龄
@end
2.Person.m文件服从协议
@implementation Person

- (id)copyWithZone:(NSZone *)zone
{
    Person *newPerson = [[[self class] allocWithZone:zone] init];
    newPerson.name = [self.name copy];
    newPerson.gender = [self.gender copy];
    newPerson.age = self.age;
    return newPerson;
}

- (id)mutableCopyWithZone:(NSZone *)zone
{
    Person *newPerson = [[[self class] allocWithZone:zone] init];
    newPerson.name = [self.name mutableCopy];
    newPerson.gender = [self.gender mutableCopy];
    newPerson.age = self.age;
    return newPerson;
}


- (void)dealloc
{
    self.name = nil;
    self.gender = nil;
    [super dealloc];
}
@end
实现,对深浅拷贝分析

       //Person copy 与 mutableCopy
        NSString *name = [NSString stringWithFormat:@"Wang"];
        NSString *gender = [NSString stringWithFormat:@"Man"];
        
        Person *per = [[Person alloc] init];
        per.name = name;
        per.gender = gender;
        NSLog(@"per = %p", per);//0x10010b980
       
        //per name = 0x100100560, gender = 0x100104ac0(拷贝前地址)
        NSLog(@"per name = %p, gender = %p", per.name, per.gender);
        
        Person *copyPerson = [per copy];
        
        //copyPerson = 0x100500a90, retaincount = 1(拷贝后地址)
        NSLog(@"copyPerson = %p, retaincount = %lu", 
                                     copyPerson, [copyPerson retainCount]);
        //(拷贝后内容地址不变,把地址拷贝过去) 
        //copyPerson name = 0x100100560, gender = 0x100104ac0 
        NSLog(@"copyPerson name = %p, gender = %p",
                                      copyPerson.name, copyPerson.gender);
    
        Person *mutaCopyPerson = [per mutableCopy];
       
        //copymutaCopyPersonPerson = 0x100401d50, retaincount = 1
        NSLog(@"copymutaCopyPersonPerson = %p, 
                retaincount = %lu", mutaCopyPerson, [mutaCopyPerson retainCount]);
         //(mutableCopy)地址不同,即拷贝是内容
        //mutaCopyPerson name = 0x100401450, gender = 0x1004014e0
        NSLog(@"mutaCopyPerson name = %p, gender = %p",
                mutaCopyPerson.name, mutaCopyPerson.gender);
        



郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。