iOS对象的拷贝

作者: Cheriez | 来源:发表于2017-02-15 16:07 被阅读16次

    一 :拷贝的相关概念

    copy语法的目的:改变副本的时候,不会影响到源对象;

    深拷贝:内容拷贝,会产生新的对象。新对象计数器置为1,源对象计数器不变。

    浅拷贝:指针拷贝,不会产生新的对象。源对象计数器+1。

    二:拷贝的实现

    实现copy,必须实现<NSCopying>协议 ,即 copyWithZone方法,返回一个不可变对象。

    实现mutableCopy,必须实现<NSMutableCoping>协议,即 mutableCopyWithZone方法 ,返回一个可变对象。

    对于数组,字典,字符串 等都已经实现了<NSCopying>的协议。

    三:数组、字典、字符串等拷贝原则

    1.对于系统的非容器类的拷贝

    对于不可变对象 ,copy实际是浅拷贝,mutableCopy是深拷贝。

    对于可变对象 ,copy、mutableCopy都是深拷贝

    2.对于系统的容器类的拷贝

    以上原则同样是适用的,但是容器类的对象都是指针拷贝。

    如果想要元素对象也是对象复制,就需要实现深拷贝。

    参考苹果官方文档

    四:自定义对象的拷贝

    Person.h

    #import@interface Person : NSObject

    @property (nonatomic,retain) NSMutableArray *apples;

    @property (nonatomic,assign) int                         age;

    @end

    Person.m

    #import "Person.h"

    @implementation Person

    - (id)copyWithZone:(NSZone *)zone{

            Person *p = [[self class] allocWithZone:zone];

            p.apples = [_apples mutableCopy];

            p.age = _age;

            return p;

    }

    @end

    测试

    Person *p = [[Person alloc] init];

    p.apples = [NSMutableArray arrayWithObjects:@"iphone",@"ipad", nil nil];

    p.age = 20;

    Person *p1 = [p copy];

    if(p != p1){

            NSLog(@"p1.age=%d",p1.age);

            NSLog(@"p1.apples=%@",p1.apples);

    }

    五:理解下property里的copy、strong区别

    copy

    #import@interface Person : NSObject

    @property (nonatomic,copy  ) NSString      *name;

    @end

    NSMutableString *string = [[NSMutableString alloc] initWithString:@"1111"];

    Person *person =[[Person alloc] init];

    person.name = string;

    [string appendString:@"1233"];

    property copy 实际上就对name干了这个:

    - (void)setName:(NSString *)name

    {

            _name = [name copy];

    }

    假设name为NSMutableString,会发生什么事?

    @property (nonatomic, copy) NSMutableString *name;

    实际上内部还是:

    - (void)setName:(NSMutableString *)name

    {

            _name = [name copy];

    }

    copy出来的仍然是不可变字符!如果有人用NSMutableString的方法,就会崩溃:

    [person.name appendString:@"1233"];

    strong

    @property (nonatomic, strong) NSString *name;

    NSMutableString *string = [NSMutableString stringWithFormat:@"汉斯哈哈哈"];

    HSPerson *person = [[HSPerson alloc] init];

    person.name = string;

    // 可以改变person.name的值,因为其内部没有生成新的对象

    [string appendString:@" hans"];

    NSLog(@"name = %@", person.name);

    相关文章

      网友评论

        本文标题:iOS对象的拷贝

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