美文网首页
细说@property(五)

细说@property(五)

作者: Chen_JF | 来源:发表于2019-02-01 10:16 被阅读0次

copy和mutableCopy

copy和mutableCopy之间的差异主要和深拷贝和浅拷贝有关,先看一下深拷贝、浅拷贝的概念。

深拷贝、浅拷贝
所谓浅拷贝,在Objective-C中可以理解为引用计数加1,并没有申请新的内存区域,只是另外一个指针指向了该区域。深拷贝正好相反,深拷贝会申请新的内存区域,原内存区域的引用计数不变。看图来说明深拷贝和浅拷贝的区别。

首先A指向一块内存区域,现在设置B = A



现在B和A指向了同一块内存区域,即为浅拷贝。

我们再来看看深考贝



首先A指向一块内存区域,现在设置B = A
A和B指向的不是同一块内存区域,只是这两块内存区域中的内容是一样的,即为深拷贝。

可变对象的copy、mutableCopy

- (void)testMutableCopy
{
    NSMutableString *str1 = [NSMutableString stringWithString:@"abc"];
    NSString *str2 = [str1 copy];
    NSMutableString *str3 = [str1 mutableCopy];
    NSLog(@"str1 = %p str2 = %p str3 = %p",str1,str2,str3);

    NSMutableArray *array1 = [NSMutableArray arrayWithObjects:@"a",@"b", nil];
    NSArray *array2 = [array1 copy];
    NSMutableArray *array3 = [array1 mutableCopy];
    NSLog(@"array1 = %p array2 = %p array3 = %p",array1,array2,array3);
}

可变对象的copy和mutableCopy都是深拷贝,那么输出结果就是:

2019-02-01 13:01:27.525064+0800 TestClock[9357:143436] str1 = 0x60000086d8f0 str2 = 0xc8c1a5736a50d5fe str3 = 0x60000086d9b0
2019-02-01 13:01:27.525064+0800 TestClock[9357:143436] array1 = 0x600000868000 array2 = 0x60000067e5a0 array3 = 0x600000868030

我们可以看到,只要是可变对象,无论是集合对象,还是非集合对象,copy和mutableCopy都是深拷贝。

不可变对象的copy、mutableCopy

- (void)testCopy
{
    NSString *str1 = @"123";
    NSString *str2 = [str1 copy];
    NSMutableString *str3 = [str1 mutableCopy];
    NSLog(@"str1 = %p str2 = %p str3 = %p",str1,str2,str3);

    NSArray *array1 = @[@"1",@"2"];
    NSArray *array2 = [array1 copy];
    NSMutableArray *array3 = [array1 mutableCopy];
    NSLog(@"array1 = %p array2 = %p array3 = %p",array1,array2,array3);
}

不可变对象的copy是浅拷贝,mutableCopy是深拷贝,那么输出结果就是:

2019-02-01 13:01:27.525064+0800 TestClock[9442:147133] str1 = 0x1045612b0 str2 = 0x1045612b0 str3 = 0x6000017e4450
2019-02-01 13:01:27.525064+0800 TestClock[9442:147133] array1 = 0x6000019f5c80 array2 = 0x6000019f5c80 array3 = 0x6000017e1170

可以看到,只要是不可变对象,无论是集合对象,还是非集合对象,copy都是浅拷贝,mutableCopy都是深拷贝。

自定义对象如何支持copy方法

项目开发中经常会有自定义对象的需求,那么自定义对象是否可以copy呢?如何支持copy?
自定义对象可以支持copy方法,我们所需要做的是:自定义对象遵守NSCopying协议,且实现copyWithZone方法。NSCopying协议是系统提供的,直接使用即可。

  • 遵守NSCopying协议:
@interface Student : NSObject <NSCopying>
{
    NSString *_sex;
}

@property (atomic, copy) NSString *name;

@property (nonatomic, copy) NSString *sex;

@property (nonatomic, assign) int age;

@end
  • 实现CopyWithZone方法:
- (instancetype)initWithName:(NSString *)name age:(int)age sex:(NSString *)sex
{
    if(self = [super init]){
        self.name = name;
        _sex = sex;
        self.age = age;
    }
    return self;
}

- (instancetype)copyWithZone:(NSZone *)zone
{
    // 注意,copy的是自己,因此使用自己的属性
    Student *stu = [[Student allocWithZone:zone] initWithName:self.name age:self.age sex:_sex];
    return stu;
}
  • 测试:
- (void)testStudent
{
    Student *stu1 = [[Student alloc] initWithName:@"Wang" age:18 sex:@"male"];
    Student *stu2 = [stu1 copy];
    NSLog(@"stu1 = %p stu2 = %p",stu1,stu2);
}
  • 结果:
stu1 = 0x600003a41e60 stu2 = 0x600003a41fc0

这里是一个深拷贝,根据copyWithZone方法的实现,应该很容易明白为何是深拷贝。
除了NSCopying协议和copyWithZone方法,对应的还有NSMutableCopying协议和mutableCopyWithZone方法,实现都是类似的,不做过多介绍。

相关文章

  • 细说@property(五)

    copy和mutableCopy copy和mutableCopy之间的差异主要和深拷贝和浅拷贝有关,先看一下深拷...

  • 细说@property(三)

    @property修饰符 定义一个属性时,nonatomic、copy、strong、assign等被称作是关键字...

  • 细说@property(一)

    @property是什么? @property = 实例变量 + get方法 + set方法 上面这段代码,可能初...

  • 细说@property(二)

    @property合成和重写 自动合成定义一个@property,在编译期间,编译器会生成实例变量、getter方...

  • 细说@property(四)

    copy和strong copy和strong的区别是面试中出现频率最高的,我们一般都知道,不可变对象属性修饰符使...

  • OC基础

    关于@property (1) @property的本质是啥编译器都帮你做了什么事儿详细说明(2) 关键字assi...

  • 面试题汇总

    ? 1. 基础 细说@property iOS基础面试题1(5.16) iOS基础面试题2 (5.24) 标哥(黄...

  • 细说那些过往(五)

    每天早上,五点。 他准时起床,穿戴整齐,戴上耳机。 外面银白色一片。 他顺着屋后的小道跑向莫森湖。 莫森湖的湖面已...

  • (五)细说路由(下)

    静态路由是指由网络管理员手工配置的路由信息。当网络的拓扑结构或链路的状态发生变化时,网络管理员需要手工去修改路由表...

  • Runtime(III)

    property_getAttributes(objc_property_t _Nonnull property)...

网友评论

      本文标题:细说@property(五)

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