探究@property申明对象属性时copy与strong的区别

时间:2023-12-16 10:55:26

一、问题来源

探究@property申明对象属性时copy与strong的区别

一直没有搞清楚NSString、NSArray、NSDictionary……属性描述关键字copy和strong的区别,看别人的项目中属性定义有的用copy,有的用strong。自己在开发中也是没有认真的去研究,至于使用copy还是用strong完全是根据心情随性而为,也一直没有出什么问题。可苹果竟然分了两个关键字,就肯定有其用意,为了提高自己还是要仔细的搞清楚其中之差别!好了,废话说完进入正题。

二、对象属性描述copy与strong的区别

直接上代码:

```

@property(nonatomic,strong) NSString strongImmutableString;

@property(nonatomic,copy) NSString
copyImmutableString;

NSMutableString *mutableStr = [NSMutableString stringWithString:@"BUSYLIFE"];
self.immutableStrongStr = mutableStr;
self.immutableCopyStr = mutableStr;
NSLog(@"StrongStr:%@",_immutableStrongStr);
NSLog(@"CopyStr:%@",_immutableCopyStr);

[mutableStr appendString:@"1987"];
NSLog(@"mutableStr:%@",mutableStr);
NSLog(@"ChangedStrongStr:%@",_immutableStrongStr);
NSLog(@"ChangedCopyStr:%@",_immutableCopyStr);

NSLog(@"StrongStrAddress:%p",_immutableStrongStr);
NSLog(@"CopyStrAddress:%p",_immutableCopyStr);
NSLog(@"mutableStrAddress:%p",mutableStr);

```

结果如下:

探究@property申明对象属性时copy与strong的区别

上面代码中我们将字符串属性指向可变的字符串,当改变可变对象内容时,strong描述的属性会跟着改变,copy描述的属性则不会,从打印结果中可以看到strongImmutableString和可变对象mutableStr的地址是一样的,而copyImmutableStr不是。

结论

为什么我们在用@property声明NSString是经常要使用copy而不是strong的原因

  1. 父类指针可以指向子类对象(如上代码中NSMutableString是NSString的子类),使用copy的目的是为了对象有更好的封装性,不受外部影响。无论外部传入可变或不可变对象,本身持有一个不可变的副本。

  2. 使用strong,属性可能指向可变对象,如果这个对象被外部更改,则该属性也会受到影响。

  3. 同样和NSString有可变子类的NSArray,NSDictionary,在声明时也应该使用copy描述。

三、对象的copy与mutablecopy

要更好的理解,我们需要搞清楚下面两种情况:

  1. 非集合对象的copy与mutablecopy

  2. 集合对象的copy与mutablecopy

在非集合类对象中:对 immutable(不可变) 对象进行 copy 操作,是指针复制,mutableCopy 操作时内容复制;对 mutable(可变) 对象进行 copy 和 mutableCopy 都是内容复制。用代码简单表示如下:

  • [immutableObject copy] // 浅复制
  • [immutableObject mutableCopy] //深复制
  • [mutableObject copy] //深复制
  • [mutableObject mutableCopy] //深复制

集合类对象是指 NSArray、NSDictionary、NSSet ... 之类的对象。下面先看集合类immutable对象使用 copy 和 mutableCopy 的一个例子:

NSArray *array = @[@"a", @"b"];
NSArray *copyArray = [array copy];
NSMutableArray *mCopyArray = [array mutableCopy];

查看内容,可以看到 copyArray 和 array 的地址是一样的,而 mCopyArray 和 array 的地址是不同的。说明 copy 操作进行了指针拷贝,mutableCopy 进行了内容拷贝。但需要强调的是:此处的内容拷贝,仅仅是拷贝 array 这个对象,array 集合内部的元素仍然是指针拷贝。

  • [immutableObject copy] // 浅复制
  • [immutableObject mutableCopy] //单层深复制
  • [mutableObject copy] //单层深复制
  • [mutableObject mutableCopy] //单层深复制

理解了这两种操作,就可以很容易的明白上面property声明NSString时用copy到底发生了什么以及他的作用了。

探究@property申明对象属性时copy与strong的区别

本文若有不对之处,欢迎大家拍砖!

最后做个小广告,前段时间写了一个抓包程序,从各大网站抓取了一些相关旅游、摄影、深度关注等领域的数据,免得浪费就维护了一个公众号。其实主要是因为我很喜欢旅游,闲暇时喜欢看看别人的旅游故事,毕竟世界那么大,我却没有足够的时间去看看,主要还是没有足够物质基础,不过看看别人的旅游也可以有很多的想象与感悟吧。也算是一种自我激励,”这个地方将来我一定也要去看看“,加油吧!!!

有和我一样爱好,也在为生活而努力拼搏的小伙伴,可以关注一下。

探究@property申明对象属性时copy与strong的区别