【iOS atomic、nonatomic、assign、copy、retain、weak、strong】的定义和区别详解
一、atomic与nonatomic
1.相同点
都是为对象添加get和set方法
2.不同点
atomic为get方法加了一把安全锁(及原子锁),使得方法get线程安全,执行效率慢
nonatomic没有添加安全锁,执行效率快
一般iOS程序中,所有属性都声明为nonatomic。这样做的原因是:
在iOS中使用同步锁的开销比较大, 这会带来性能问题。一般情况下并不要求属性必须是“原子的”,因为这并不能保证“线程安全”(thread safety),若要实现“线程安全”的操作,还需采用更为深层的锁定机制才醒。
例如:一个线程在连续多次读取某个属性值的过程中有别的线程在同时改写该值,那么即便将属性声明为atomic,也还是会读取到不同的属性值。
二、assign,copy与retain
assign: 简单赋值,不更改索引计数(Reference Counting)。
copy: 建立一个索引计数为1的对象,然后释放旧对象
retain:释放旧的对象,将旧对象的值赋予输入对象,再提高输入对象的索引计数为1
这里做一个简单的隐喻:
在系统内存中malloc 创建了一个房子A(及为对象分配内存),我A的地址告诉管理者a,(A房子管理者数+1)
情况1、assign b来的情况,由于是弱对象,管理a只能给b间接使用权,不告诉它地址,所以管理者还是只有a一个,这个时候因为b是弱对象,a如果离开了,A这个房子就没管理者了。A房子就会被系统收回,b成为野孩子了,野孩子乱找内存操作容易导致系统奔溃。
情况2、retain c 来的情况,c拥有一个地址拷贝技能,拷贝了a知道的A房子的地址住所,然后把a谋杀了,系统(A房子管理者数-1),同时c成为新的管理者(A房子管理者数+1)
情况3、copy d来的情况,d有一个好的技能,看到好的东西立马拷贝一份专属自己的,d给拷贝来的新房子命名成D,系统划分了一个新的底盘给d(D房子管理者数+1),然后d把a也谋杀了,(A房子管理者数-1),A房子没有管理者,系统回收了A房子这块地
三、weak 和strong的区别:
(weak和strong)不同的是 当一个对象不再有strong类型的指针指向它的时候 它会被释放 ,即使还有weak型指针指向它。
一旦最后一个strong型指针离去 ,这个对象将被释放,所有剩余的weak型指针都将被清除。
可能有个例子形容是妥当的。
想象我们的对象是一条狗,狗想要跑掉(被释放)。
strong型指针就像是栓住的狗。只要你用牵绳挂住狗,狗就不会跑掉。如果有5个人牵着一条狗(5个strong型指针指向1个对象),除非5个牵绳都脱落 ,否着狗是不会跑掉的。
weak型指针就像是一个小孩指着狗喊到:“看!一只狗在那” 只要狗一直被栓着,小孩就能看到狗,(weak指针)会一直指向它。只要狗的牵绳脱落,狗就会跑掉,不管有多少小孩在看着它。
只要最后一个strong型指针不再指向对象,那么对象就会被释放,同时所有的weak型指针都将会被清除。
使用建议:
当用copy时,set方法会先release旧值,再copy一个新的对象,reference count 为1(减少了对上下文的依赖);当用assign,直接赋值,无retain操作。当用retain,release旧值,retain新值;
非ARC
• 1> copy : 只用于NSString\block
• 2> retain : 除NSString\block以外的OC对象
• 3> assign : 基本数据类型、枚举、结构体(非OC对象),当2个对象相互引用,一端用retain,一端用assign
•2.ARC
• 1> copy : 只用于NSString\block
• 2> strong : 除NSString\block以外的OC对象
• 3> weak : 当2个对象相互引用,一端用strong,一端用weak
4> assgin : 基本数据类型、枚举、结构体(非OC对象)
NSString、NSArray、NSDictionary 等等经常使用copy关键字,是因为他们有对应的可变类型:NSMutableString、NSMutableArray、NSMutableDictionary;
block 使用 copy 是从 MRC 遗留下来的“传统”,在 MRC 中,方法内部的 block 是在栈区的,使用 copy 可以把它放到堆区.在 ARC 中写不写都行:对于 block 使用 copy 还是 strong 效果是一样的,但写上 copy 也无伤大雅,还能时刻提醒我们:编译器自动对 block 进行了 copy 操作。如果不写 copy ,该类的调用者有可能会忘记或者根本不知道“编译器会自动对 block 进行了 copy 操作”,他们有可能会在调用之前自行拷贝属性值。这种操作多余而低效。
下面做下解释: copy 此特质所表达的所属关系与 strong 类似。然而设置方法并不保留新值,而是将其“拷贝” (copy)。 当属性类型为 NSString 时,经常用此特质来保护其封装性,因为传递给设置方法的新值有可能指向一个 NSMutableString 类的实例。这个类是 NSString 的子类,表示一种可修改其值的字符串,此时若是不拷贝字符串,那么设置完属性之后,字符串的值就可能会在对象不知情的情况下遭人更改。所以,这时就要拷贝一份“不可变” (immutable)的字符串,确保对象中的字符串值不会无意间变动。只要实现属性所用的对象是“可变的” (mutable),就应该在设置新属性值时拷贝一份。
用@property 声明 NSString、NSArray、NSDictionary 经常使用 copy 关键字,是因为他们有对应的可变类型:NSMutableString、NSMutableArray、NSMutableDictionary,他们之间可能进行赋值操作,为确保对象中的字符串值不会无意间变动,应该在设置新属性值时拷贝一份。
单独介绍下copy使用Nsstring
推荐这个博客,解释详细http://blog.csdn.net/itianyi/article/details/9018567
引用里面的第一句话其实说白了,对字符串为啥要用这两种方式?我觉得还是一个安全问题,比如声明的一个NSString *str变量,然后把一个NSMutableString *mStr变量的赋值给它了,如果要求str跟着mStr变化,那么就用retain;如果str不能跟着mStr一起变化,那就用copy。而对于要把NSString类型的字符串赋值给str,那两都没啥区别。不会影响安全性,内存管理也一样。
【iOS atomic、nonatomic、assign、copy、retain、weak、strong】的定义和区别详解的更多相关文章
- 【整理】Object-C中的属性(Property)的Setter:assign,copy,retain,weak,strong之间的区别和联系
iOS编程过程中,经常看到一些属性前面有些修饰符,比如copy,retain等. 这些关键字,是Object-C语言中,对于Property的setter. Mac官网: The Objective- ...
- iOS开发知识点:理解assign,copy,retain变strong
一..h和.m文件的变化说明 1.对于.h头文件,主要是将属性定义由retain变为strong @property (retain, nonatomic) 变为 @property (strong, ...
- 理解assign,copy,retain变strong
举个例子: NSString *houseOfMM = [[NSString alloc] initWithString:'装梵几的三室两厅']; 上面一段代码会执行以下两个动作: 1 在堆上分配一 ...
- nonatomic, retain,weak,strong用法详解
strong weak strong与weak是由ARC新引入的对象变量属性 ARC引入了新的对象的新生命周期限定,即零弱引用.如果零弱引用指向的对象被deallocated的话,零弱引用的对象会被自 ...
- NSString NSMutableString copy mutableCopy retain weak strong整合
copy retain assign的差别在于对象属性的set方法 NSString 与 NSMutableString NSString是不可变字符串对象,这句话的意思,结合代码: #import ...
- 对于atomic nonatomic assign retain copy strong weak的简单理解
atomic和nonatomic用来决定编译器生成的getter和setter是否为原子操作 1)atomic 设置成员变量的@property属性时,atomic是默认值,提供多线程安全 在多线程环 ...
- iOS之属性修饰符 retain、strong和copy区别测试
时不时会有点迷惑属性修饰符retain.strong.copy三者之间的区别,还是把测试过程记录下来好一点! 1.属性修饰符结论 2.给retain.strong.copy修饰的字符串属性赋值指针变化 ...
- Objective C assign© & retain区别
什么是assign,copy,retain之间的区别? assign: 简单赋值,不更改索引计数(Reference Counting). copy: 建立一个索引计数为1的对象,然后释放旧对象 re ...
- iOS MJRefresh下拉刷新(上拉加载)使用详解
下拉刷新控件目前比较火的有好几种,本人用过MJRefresh 和 SVPullToRefresh,相对而言,前者比后者可定制化.拓展新都更高一点. 因此本文着重讲一下MJRefresh的简单用法. 导 ...
随机推荐
- Spring_的jar详细说明
org.springframework.aop ——Spring的面向切面编程,提供AOP(面向切面编程)的实现 org.springframework.asm——spring 2.5.6的时候需要a ...
- SQL Server数据库SP命令祥解
1.数据库: (1)sp_helpdb:报告有关指定数据库或所有数据库的信息.例:sp_helpdb --显示所有数据库信息(名称.大小等)例:sp_helpdb Recruitment -- ...
- JS学习:第一周——NO.3面向对象
[面向对象基础知识] 封装:对于功能相同的代码,我们只需封装一次,以后再遇到类似的功能,只需调用即可,无需重写,避免大量冗余代码. 对象的特征:方法和属性: 面向对象的特点: 封装:低耦合高内聚: 继 ...
- Markdown编辑器:Typora
现在网上的Markdown有很多,各有各的特色,同时也有各自的缺点.比如有的传图片比较麻烦,有的导出pdf需要付费,有的数学公式编辑比较麻烦等等...... 而最近接触到Typora,发现这真是一款良 ...
- [COJ2201][KOJ0223][KOJ0250]花园
[KOJ0223][KOJ0250]花园 试题描述 小奇的花园有n个温室,标号为1到n,温室以及以及温室间的双向道路形成一棵树. 每个温室都种植着一种花,随着季节的变换,温室里的花的种类也在不断发生着 ...
- 设计模式--适配器模式Adapter(结构型)
一.适配器模式 适配器模式的主要作用是在新接口和老接口之间进行适配.将一个类的接口转换成客户端期望的另外一个接口.其实适配器模式有点无赖之举,在前期设计的时候,我们就不应该考虑适配器模式,而应该通过重 ...
- CorelDRAW x6 X8安装失败解决方法
CorelDRAW x6 X8自定义安装时,到最后经常会出现以下问题: 解决方法如下: 在自定义安装时,出现以下这个界面时,点击红色箭头的地方 将下图红色箭头指向的选项,点击取消,不要选上,即可解决安 ...
- Android 通用流行框架
原文出处: http://android.jobbole.com/83028/ 1. 缓存 名称 描述 DiskLruCache Java实现基于LRU的磁盘缓存 2.图片加载 名称 描述 Andro ...
- MongoDB 学习笔记一: 配置
下载MongoDB 下载地址:https://www.mongodb.com/download-center?jmp=nav#community 这里是在windows平台下安装MongoDB, 下载 ...
- ios 项目的.gitignore
git作为代码管理工具,.gitignore文件用来忽略哪些哪些文件不用添加到仓库管理https://www.gitignore.io/ 这个网址输入变成语言会帮你生成常用的忽略文件如:IOS项目,输 ...