美文网首页
iOS内存管理之copy mutableCopy

iOS内存管理之copy mutableCopy

作者: 夜凉听风雨 | 来源:发表于2021-11-03 23:09 被阅读0次

    不可变类型调用copy方法是不可变类型。
    可变类型调用copy方法会复制出不可变类型。
    不可变类型调用mutableCopy方法会复制出可变类型。
    可变类型调用mutableCopy方法会复制出可变类型。

    不可变类型调用copy方法不会拷贝出一个副本,只会增加引用计数,指向的还是之前的地址,所以称之为浅拷贝。

    浅拷贝.png

    不可变类型和可变类型调用mutableCopy方法或者可变类型调用copy方法都会拷贝出一个副本,指向的地址和之前的地址完全不同,所以称之为深拷贝。

    可变类型深拷贝.png 可变类型深拷贝.png 不可变类型深拷贝.png

    说到copy操作 ,不得不说NSCopying和NSMutableCopying协议。
    如果类想要支持copy操作,则必须实现NSCopying协议,也就是说实现copyWithZone方法;
    如果类想要支持mutableCopy操作,则必须实现NSMutableCopying协议,也就是说实现mutableCopyWithZone方法;
    iOS系统中的一些类已经实现了NSCopying或者NSMutableCopying协议的方法,如果向未实现相应方法的系统类或者自定义类发送copy或者mutableCopy消息,则会crash。

    自定义的类型

    现在创建一个Person类继承自NSObject,如果对Person类对象调用copy方法,我们需要在Person类里遵守NSCopying协议,并实现- (id)copyWithZone:(NSZone *)zone协议方法。

    - (id)copyWithZone:(NSZone *)zone{    
         Person *model = [[[self class] allocWithZone:zone] init];
         model.name = self.name;
         model.age  = self.age;
         // 未公开的成员
         model->_nickName = _nickName;
         // 可变的成员
         model.cars = [self.cars mutableCopyWithZone:zone];
         return model;
    }
    

    说明:在- (id)copyWithZone:(NSZone *)zone方法中,一定要通过[self class]方法返回的对象调用allocWithZone:方法。因为指针可能实际指向的是Person的子类。这种情况下,通过调用[self class],就可以返回正确的类的类型对象。

        Person *p1 = [[Person alloc] init];
        p1.name = @"Jonas";
        p1.age = 28;
        p1.cars = [NSMutableArray alloc] init];
        [p1.cars addObject:@"奔驰"];
        [p1.cars addObject:@"宝马"];
    
        Person *p2 = [p1 copy];
        NSLog(@"p1===%p, p2===%p", p1, p2); 
        NSLog(@"name==%@, age==%ld", p2.name, p2.age); 
    

    打印结果:

    p1===0x600003530f20, p2===0x600003530fe0
    name==Jonas, age==28
    

    可以看到p1和p2地址是不同的,但是name和age是一样的。

    相关文章

      网友评论

          本文标题:iOS内存管理之copy mutableCopy

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