iOS开发-------属性用copy、strong修饰的区别

原创 2016年02月29日 19:49:24

       Copy,Strong的区别需要了解点内存管理的知识,Strong是ARC下引入的修饰,相当于手动管理内存(MRC)下的retain,在相关代码下,常常看到有的人用copy修饰NSString,NSArray,NSDictionary..等存在可变与不可变之分的对象,常常会用copy,而不是strong,下面代码来解释一下strong与copy的区别:

先说明一下什么叫做浅拷贝,什么叫做深拷贝;

浅Copy:可以理解为指针的复制,只是多了一个指向这块内存的指针,共用一块内存。

深Copy:理解为内存的复制,两块内存是完全不同的,也就是两个对象指针分别指向不同的内存,互不干涉。


首先在类延展中声明两个属性变量

@property (nonatomic, strong)NSString * stringStrong;   //strong修饰的字符串对象
@property (nonatomic, copy)NSString * stringCopy;       //copy修饰的字符串对象

接着创建两个不可变字符串(NSString)

//新创建两个NSString对象
NSString * strong1 = @"I am Strong!";
NSString * copy1 = @"I am Copy!";

将两个属性分别进行赋值

//初始化两个字符串
self.stringStrong = strong1;
self.stringCopy = copy1;

分别打印一下四个变量的内存地址:

NSLog(@"strong1 = %p",strong1);
NSLog(@"stringStrong = %p",self.stringStrong);
NSLog(@"copy1 = %p",copy1);
NSLog(@"stringCopy = %p",self.stringCopy);

结果如下:可以看出,此时无论是strong修饰的字符串还是copy修饰的字符串,都进行了浅Copy.

2016-02-29 18:59:06.332 StrongOrCopy[5046:421886] strong1 = 0x10a0b3078
2016-02-29 18:59:06.332 StrongOrCopy[5046:421886] stringStrong = 0x10a0b3078
2016-02-29 18:59:06.332 StrongOrCopy[5046:421886] copy1 = 0x10a0b3098
2016-02-29 18:59:06.332 StrongOrCopy[5046:421886] stringCopy = 0x10a0b3098


如果创建两个不可变字符串对象(NSMutableString)呢

//新创建两个NSMutableString对象
NSMutableString * mutableStrong = [NSMutableString stringWithString:@"StrongMutable"];
NSMutableString * mutableCopy = [NSMutableString stringWithString:@"CopyMutable"];
分别对属性再次进行赋值
self.stringStrong = mutableStrong;
self.stringCopy = mutableCopy;

分别打印一下四个变量的地址:结果如下:这时就发现了,用strong修饰的字符串依旧进行了浅Copy,而由copy修饰的字符串进行了深Copy,所以mutableStrong与stringStrong指向了同一块内存,而mutableCopy和stringCopy指向的是完全两块不同的内存。

2016-02-29 18:59:06.332 StrongOrCopy[5046:421886] mutableStrong = 0x7fccba425d60
2016-02-29 18:59:06.332 StrongOrCopy[5046:421886] stringStrong = 0x7fccba425d60
2016-02-29 18:59:06.332 StrongOrCopy[5046:421886] mutableCopy = 0x7fccba40d7c0
2016-02-29 18:59:06.333 StrongOrCopy[5046:421886] stringCopy = 0x7fccba4149e0


那么有什么用呢,实例来看一下有什么区别:

首先是对不可变字符串进行操作:

//新创建两个NSString对象
NSString * strong1 = @"I am Strong!";
NSString * copy1 = @"I am Copy!";

//初始化两个字符串
self.stringStrong = strong1;
self.stringCopy = copy1;

//两个NSString进行操作
[strong1 stringByAppendingString:@"11111"];
[copy1 stringByAppendingString:@"22222"];
分别对在字符串后面进行拼接,当然这个拼接对原字符串没有任何的影响,因为不可变自字符串调用的方法都是有返回值的,原来的值是不会发生变化的.打印如下,对结果没有任何的影响:

2016-02-29 19:15:26.729 StrongOrCopy[5146:439360] strong1 = I am Strong!
2016-02-29 19:15:26.729 StrongOrCopy[5146:439360] stringStrong = I am Strong!
2016-02-29 19:15:26.729 StrongOrCopy[5146:439360] copy1 = I am Copy!
2016-02-29 19:15:26.729 StrongOrCopy[5146:439360] stringCopy = I am Copy!


然后是对可变字符串进行操作:

//新创建两个NSMutableString对象
NSMutableString * mutableStrong = [NSMutableString stringWithString:@"StrongMutable"];
NSMutableString * mutableCopy = [NSMutableString stringWithString:@"CopyMutable"];

//初始化两个字符串
self.stringStrong = mutableStrong;
self.stringCopy = mutableCopy;

//两个MutableString进行操作
[mutableStrong appendString:@"Strong!"];
[mutableCopy appendString:@"Copy!"];

           再来看一下结果:对mutableStrong进行的操作,由于用strong修饰的stringStrong没有进行深Copy,导致共用了一块内存,当mutableStrong对内存进行了操作的时候,实际上对stringStrong也进行了操作;   相反,用copy修饰的stringCopy进行了深Copy,也就是说stringCopy与mutableCopy用了两块完全不同的内存,所以不管mutableCopy进行了怎么样的变化,原来的stringCopy都不会发生变化.这就在日常中避免了出现一些不可预计的错误。
2016-02-29 19:20:27.652 StrongOrCopy[5245:446189] stringStrong = StrongMutableStrong!
2016-02-29 19:20:27.652 StrongOrCopy[5245:446189] mutableStrong = StrongMutableStrong!
2016-02-29 19:20:27.652 StrongOrCopy[5245:446189] stringCopy = CopyMutable
2016-02-29 19:20:27.652 StrongOrCopy[5245:446189] mutableCopy = CopyMutableCopy!

     这样看来,在不可变对象之间进行转换,strong与copy作用是一样的,但是如果在不可变与可变之间进行操作,那么楼主比较推荐copy,这也就是为什么很多地方用copy,而不是strong修饰NSString,NSArray等存在可变不可变之分的类对象了,避免出现意外的数据操作.



版权声明:本文为博主原创文章,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接。

NSString什么时候用copy,什么时候用strong

大部分的时候NSString的属性都是copy,那copy与strong的情况下到底有什么区别呢? 比如: @property (retain,nonatomic) NSStri...
  • itianyi
  • itianyi
  • 2013年06月04日 00:49
  • 40336

IOS开发中copy和retain的区别

在ios开发中我们一般都这么定义:@property (nonatomic,copy) NSString *name,而不这么定义:@property (nonatomic,retain) NSStr...
  • feisongfeiqin
  • feisongfeiqin
  • 2015年12月09日 19:35
  • 1240

strong 和 copy关键字的区别

内存管理 1.什么是ARC? ARC是automatic reference counting自动引用计数,在程序编译时自动加入retain/release。在对象被创建时retain c...
  • luyangMVP
  • luyangMVP
  • 2016年08月11日 19:29
  • 721

iOS 属性中strong,weak,assign,retain,copy等特性

iOS 内存管理 属性中strong,weak,assign,retain,copy特性的学习
  • a380880304
  • a380880304
  • 2015年09月06日 11:00
  • 2657

[iOS]NSString到底使用Copy还是使用Strong属性,有什么区别

以前在自学OC的时候和实际的项目中,都没有关注这一个小问题,一直使用Strong属性声明,也没发现项目中出现过由于NSString导致的未知Bug。 某一天看到南峰子的blog,我也来测试以下看看具体...
  • weweco
  • weweco
  • 2015年07月28日 17:13
  • 2860

iOS内存管理(6)--NSArray与NSMutableArray用copy修饰还是strong

一、NSMutableArray 被copy、strong修饰后的变化: 把NSMutableArray用copy修饰有时就会crash,因为对这个数组进行了增删改操作,而copy后的数组变成了不可...
  • Winzlee
  • Winzlee
  • 2016年06月24日 15:31
  • 11000

NSString类型的属性一般用copy修饰,而不是用strong来修饰。

从一句代码规范说起: NSString类型的属性一般用copy修饰,而不是用strong来修饰。 看过一些文章后,总结:        举个例子 创建一个Person对象,设置属性用strong修...
  • SUMMER_csdn123
  • SUMMER_csdn123
  • 2016年08月12日 13:38
  • 992

对可修改类型的属性使用copy特性

前两天去网易面试的时候面试官在问内存管理特性的时候问到了这样一个问题:能不能对一个是可变类型的属性采用copy特性,我当时的回答是不能,面试官问为什么不能,当时没有想到原因,但是因为自己遇到过把一个N...
  • ShorewB
  • ShorewB
  • 2016年08月21日 21:35
  • 1141

copy,mutableCopy 理解

copy,mutableCopy 理解 好记性不如烂笔头,好理解不如写出来,前一句非常正确,后一句是我加的,嘿嘿。 突击学习了下2者的却别,记录如下。 OC中可变对象和不可对象经常用的如下: NSSt...
  • fg313071405
  • fg313071405
  • 2013年11月21日 12:02
  • 7475

NSString不用strong而用copy修饰的原因

以前一直没有彻底弄明白这其中的原因,今天终于懂了,分享给还没有懂的人~ 直接上代码: @interface Test : NSObject @property (nonatomic, st...
  • qq_18425655
  • qq_18425655
  • 2016年05月11日 13:07
  • 2146
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:iOS开发-------属性用copy、strong修饰的区别
举报原因:
原因补充:

(最多只允许输入30个字)