转:NSString什么时候用copy,什么时候用strong
大部分的时候NSString的属性都是copy,那copy与strong的情况下到底有什么区别呢?
比如:
@property (retain,nonatomic) NSString *rStr;
@property (copy, nonatomic) NSString *cStr;
- (void)test:
{
NSMutableString *mStr = [NSMutableStringstringWithFormat:@"abc"];
self.rStr = mStr;
self.cStr = mStr;
NSLog(@"mStr:%p,%p", mStr,&mStr);
NSLog(@"retainStr:%p,%p", _rStr, &_rStr);
NSLog(@"copyStr:%p,%p", _cStr, &_cStr);
}
假如,mStr对象的地址为0x11,也就是0x11是@“abc”的首地址,mStr变量自身在内存中的地址为0x123;
当把mStr赋值给retain的rStr时,rStr对象的地址为0x11,rStr变量自身在内存中的地址为0x124;rStr与mStr指向同样的地址,他们指向的是同一个对象@“abc”,这个对象的地址为0x11,所以他们的值是一样的。
当把mStr赋值给copy的cStr时,cStr对象的地址为0x22,cStr变量自身在内存中的地址0x125;cStr与mStr指向的地址是不一样的,他们指向的是不同的对象,所以copy是深复制,一个新的对象,这个对象的地址为0x22,值为@“abc”。
如果现在改变mStr的值:
[mStr appendString:@"de"];
NSLog(@"retainStr:%@", _rStr);
NSLog(@"copyStr:%@", _cStr);
结果,
使用retain的字串rStr的值:@"abcde",
而使用copy的字串cStr的值:@"abc",
所以,如果一般情况下,我们都不希望字串的值跟着mStr变化,所以我们一般用copy来设置string的属性。
如果希望字串的值跟着赋值的字串的值变化,可以使用strong,retain。
注意:上面的情况是针对于当把NSMutableString赋值给NSString的时候,才会有不同,如果是赋值是NSString对象,那么使用copy还是strong,结果都是一样的,因为NSString对象根本就不能改变自身的值,他是不可变的。
把一个对象赋值给一个属性变量,当这个对象变化了,如果希望属性变量变化就使用strong属性,如果希望属性变量不跟着变化,就是用copy属性。
由此可以看出:
对源头是NSMutableString的字符串,retain仅仅是指针引用,增加了引用计数器,这样源头改变的时候,用这种retain方式声明的变量(无论被赋值的变量是可变的还是不可变的),它也会跟着改变;而copy声明的变量,它不会跟着源头改变,它实际上是深拷贝。
对源头是NSString的字符串,无论是retain声明的变量还是copy声明的变量,当第二次源头的字符串重新指向其它的地方的时候,它还是指向原来的最初的那个位置,也就是说其实二者都是指针引用,也就是浅拷贝。
另外说明一下,这两者对内存计数的影响都是一样的,都会增加内存引用计数,都需要在最后的时候做处理。
其实说白了,对字符串为啥要用这两种方式?我觉得还是一个安全问题,比如声明的一个NSString *str变量,然后把一个NSMutableString *mStr变量的赋值给它了,如果要求str跟着mStr变化,那么就用retain;如果str不能跟着mStr一起变化,那就用copy。而对于要把NSString类型的字符串赋值给str,那两都没啥区别。不会影响安全性,内存管理也一样。
转:NSString什么时候用copy,什么时候用strong的更多相关文章
- NSString copy or not (strong)?
前些日子笔者一直在维护公司的一些旧项目,项目里面的NSString属性几乎全部用的strong,而我在给项目增加一些新的功能的,又都用的copy,因为在我的脑子里几乎已经把NSString大部分 ...
- NSString 为什么要使用copy,而不是retain
NSString 为什么要使用copy,而不是retain1.首先如果使用retain,只是引用计数+1,并没有生成新的对象,所以效率好2.但是使用copy安全.因为NSString 为 NSMuta ...
- NSString 属性为啥用copy 不用strong
copy不能修改,strong可以修改,防止字符串被意外修改.demo: ——————————————————code 你要的 demo—————————————————— @property (n ...
- block要用copy修饰,还是用strong
栈区与堆区 block本身是像对象一样可以retain,和release.但是,block在创建的时候,它的内存是分配在栈(stack)上,而不是在堆(heap)上.他本身的作于域是属于创建时候的作用 ...
- IOS 关于NSString类型的属性为什么有时用copy,有时用strong呢?
对于很多初学者,发现在修饰NSString类型的对象时,会有这样的疑惑?怎么有些人用strong修饰,而有些人用copy修饰呢? 这里有个例子,一.首先声明2个属性: @property (nonat ...
- NSString NSMutableString copy mutableCopy retain weak strong整合
copy retain assign的差别在于对象属性的set方法 NSString 与 NSMutableString NSString是不可变字符串对象,这句话的意思,结合代码: #import ...
- 【转】 NSString什么时候用copy,什么时候用strong
原文: http://blog.csdn.net/itianyi/article/details/9018567 大部分的时候NSString的属性都是copy,那copy与strong的情况下到底有 ...
- NSString和NSMutablestring,copy和strong(转载)
1.http://www.cocoachina.com/ios/20150512/11805.html 2.http://blog.csdn.net/winzlee/article/details/5 ...
- NSString为何要用copy修饰,而不是strong?
NSString本身是无所谓的,但是如果一个 NSString 指针指向了一个 NSMutableString的内存空间的话,如果使用 strong 修饰的话,如果你在别处修改这个值的话,那么原来的值 ...
随机推荐
- Day4:T1小技巧(类似于指针操作)T2搜索+小细节
Day4:其中有很多小技巧get T1 一直没有听到过像这样的小技巧的略专业名词,有点类似于指针操作,之前有碰到过很多这样的题目 每次都是以不同的形式出现,但是感觉思想还是有点接近的吧(就比如某天有一 ...
- NoSQL发展简史、粗略分类及选择
这里对近来看的部分NoSQL资料做一个汇总记录,主要包括简史.粗略分类及数据库选择的考虑事项.NoSQL常见的解释是“non-relational”,有时也称作Not Only SQL. 1. ...
- [原]逆向iOS SDK -- “添加本地通知”的流程分析
观点: 代码面前没有秘密 添加通知的 Demo 代码 - (void)scheduleOneLocalNotification { [[UIApplication sharedApplication] ...
- 由ASP.NET所谓前台调用后台、后台调用前台想到HTTP
由ASP.NET所谓前台调用后台.后台调用前台想到HTTP 在由ASP.NET所谓前台调用后台.后台调用前台想到HTTP——理论篇中描述了一下ASP.NET新手的三个问题及相关的HTTP协议内容,在由 ...
- JS OffsetParent属性
offsetParent 属性返回一个对象的引用,这个对象是距离调用offsetParent的元素最近的(在包含层次中最靠近的),并且是已进行过CSS定位的容器元素. 如果这个容器元素未进行CS ...
- 受众定向-Topic Model
注:这一节我忽略,如果今后有时候,我会整理一份Topic Model的资料来说明,因为原课程中面向的是可能本来就熟悉Topic Model的听众,讲这课只是举个例子,带大家复习一下,所以即使整理出来, ...
- Query插件
推荐一些常用感觉不错的jQuery插件 JQuery插件繁多,下面是个人在工作和学习中用到感觉不错的,特此记录. UI: jquery UI(官方的UI插件,很好很强大功能完备,灵活性很强,有十几套主 ...
- jquery animate stop函数解析
今天我们来看看jquery中动画操作的stop函数.其实我至今不是很明白啊,所以此文算是求救以及抛砖引玉. 在jquery 1.7版本以前,stop支持两个参数,分别是clearQueue和jumpT ...
- 线程内唯一对象HttpContext
在asp.net中,HttpContext是主线程内唯一对象.在web应用中开启多线程,在另外一个线程中是无法访问HttpContext. 如果需要在另外一个线程中使用HttpContext.Curr ...
- Linux登录ssh携带密码
最近在使用ssh,但是每次都需要输入密码,想简单一步搞定,Google了一下,发现了一个比较笨的但实用的方法 1.安装 sshpass sudo apt-get install sshpass 2.携 ...