在IOS开发中,经常会使用   @property(nonatomic,copy)NSString * name;   语句来快速设置set get 方法,在此依次说明atomic 、nonatomic、copy 、retain的作用

        atomic 和 nonatomic 用来决定编译器生成的 getter和  setter  是原子操作还是非原子操作。

        atomic

设置成员变量的@property属性时,默认为atomic,即原子操作,对同一对象的set和get的操作是顺序执行的,以提供多线程安全。

在多线程环境下,原子操作是必要的,否则有可能引起错误的结果。加了atomic,setter函数会变成下面这样:
                        {lock}
                                if (property != newValue) { 
                                        [property release]; 
                                        property = [newValue retain]; 
                                }
                        {unlock}

  即在有新的值赋给变量时,释放原来的值,并将新传来的值赋给变量;

        nonatomic

  nonatomic:非原子性访问,对属性赋值的时候不加锁,多线程并发访问会提高性能。如果不加此属性,则默认是两个访问方法都为原子型事务访问

禁止多线程,变量保护,提高性能。

atomic是Objc使用的一种线程保护技术,基本上来讲,是防止在写未完成的时候被另外一个线程读取,造成数据错误。而这种机制是耗费系统资源的,所以在iPhone这种小型设备上,如果没有使用多线程间的通讯编程,那么nonatomic是一个非常好的选择。

指出访问器不是原子操作,而默认地,访问器是原子操作。这也就是说,在多线程环境下,解析的访问器提供一个对属性的安全访问,从获取器得到的返回值或者通过设置器设置的值可以一次完成,即便是别的线程也正在对其进行访问。如果你不指定 nonatomic ,在自己管理内存的环境中,解析的访问器保留并自动释放返回的值,如果指定了 nonatomic ,那么访问器只是简单地返回这个值。

assign   针对基础数据类型 (NSInteger,CGFloat)和C数据类型(int, float, double, char)等等。

默认类型,setter方法直接赋值,而不进行retain操作, 适用于基本数据类型, 对对象类型, 不会发生引用计数变化

此标记说明设置器直接进行赋值,这也是默认值。在使用垃圾收集的应用程序中,如果你要一个属性使用assign,且这个类符合NSCopying协议,你就要明确指出这个标记,而不是简单地使用默认值,否则的话,你将得到一个编译警告。这再次向编译器说明你确实需要赋值,即使它是可拷贝的。

retain   对其他NSObject和其子类对参数进行release旧值,再retain新值

retain是给属性的引用计数加1,这里的retain是指,这个setter会给参数的引用计数加1
       
        指定retain会在赋值时唤醒传入值的retain消息。此属性只能用于Objective-C对象类型,而不能用于Core Foundation对象。(原因很明显,retain会增加对象的引用计数,而基本数据类型或者Core Foundation对象都没有引用计数——译者注)。

 注意: 把对象添加到数组中时,引用计数将增加对象的引用次数+1。

copy

@property(nonatomic copy)NSString *str;//被修饰的属性不可变;

对NSString 它指出,在赋值时使用传入值的一份拷贝拷贝工作由copy方法执行,此属性只对那些实行了NSCopying协议的对象类型有效。

copy与retain:

copy:建立一个索引计数为1的对象,然后释放旧对象

Copy其实是建立了一个相同的对象,而retain不是:
1.比如一个NSString 对象,地址为0×1111 ,内容为@”STR”,Copy 到另外一个NSString 之后,地址为0×2222 ,内容相同。

2.新的对象retain为1 ,旧有对象没有变化,retain 到另外一个NSString 之后,地址相同(建立一个指针,指针拷贝),内容当然相同,这个对象的retain值+1。
总结:retain 是指针拷贝,copy 是内容拷贝。

assign与retain:

1. 接触过C,那么假设你用malloc分配了一块内存,并且把它的地址赋值给了指针a,后来你希望指针b也共享这块内存,于是你又把a赋值给(assign)了b。此时a和b指向同一块内存,请问当a不再需要这块内存,能否直接释放它?答案是否定的,因为a并不知道b是否还在使用这块内存,如果a释放了,那么b在使用这块内存的时候会引起程序crash掉。

2. 了解到1中assign的问题,那么如何解决?最简单的一个方法就是使用引用计数(reference counting),还是上面的那个例子,我们给那块内存设一个引用计数,当内存被分配并且赋值给a时,引用计数是1。当把a赋值给b时引用计数增加到2。这时如果a不再使用这块内存,它只需要把引用计数减1,表明自己不再拥有这块内存。b不再使用这块内存时也把引用计数减1。当引用计数变为0的时候,代表该内存不再被任何指针所引用,系统可以把它直接释放掉。
总结:上面两点其实就是assign和retain的区别,assign就是直接赋值,从而可能引起1中的问题,当数据为int, float等原生类型时,可以使用assign。retain就如2中所述,使用了引用计数,retain引起引用计数加1, release引起引用计数减1,当引用计数为0时,dealloc函数被调用,内存被回收。                                                                                 

Automatic Reference Counting(自动引用计数)简称ARC

Strong Reference,强引用。默认类型,不加任何关键字(也可以写成__strong)。相当于之前的retain属性。

Weak Reference,弱引用。不增加计数,当对象开始释放时,立刻设置成nil。

参考资料:http://blog.sina.com.cn/s/blog_834f346f0100s7iq.html

http://www.cnblogs.com/jelink/articles/2281698.html

http://clang.llvm.org/docs/AutomaticReferenceCounting.html

http://www.cnblogs.com/pengyingh/articles/2375080.html

http://www.xuebuyuan.com/1762493.html

                                                                         

Objective-C 中的 assign, copy,retain,strong,weak 详解的更多相关文章

  1. 关于@property()的那些属性及ARC简介【nonatomic,atomic,assign,retain,strong,weak,copy。】

    @property()常用的属性有:nonatomic,atomic,assign,retain,strong,weak,copy. 其中atomic和nonatomic用来决定编译器生成的gette ...

  2. opencv中 int main(int argc,char* argv[])详解

    opencv中  int main(int argc,char* argv[])详解 argc是命令行总的参数个数     argv[]是argc个参数,其中第0个参数是程序的全名,以后的参数     ...

  3. CSS中伪类及伪元素用法详解

    CSS中伪类及伪元素用法详解   伪类的分类及作用: 注:该表引自W3School教程 伪元素的分类及作用: 接下来让博主通过一些生动的实例(之前的作业或小作品)来说明几种常用伪类的用法和效果,其他的 ...

  4. SVN组成中trunk,branches and tags功能用法详解

    SVN组成中trunk,branches and tags功能用法详解  我相信初学开发在SVN作为版本管理时,都估计没可能考虑到如何灵活的运用SVN来管理开发代码的版本,下面我就摘录一篇文章来简单说 ...

  5. UIViewController中各方法调用顺序及功能详解

    UIViewController中各方法调用顺序及功能详解 UIViewController中loadView, viewDidLoad, viewWillUnload, viewDidUnload, ...

  6. 单元测试系列之四:Sonar平台中项目主要指标以及代码坏味道详解

    更多原创测试技术文章同步更新到微信公众号 :三国测,敬请扫码关注个人的微信号,感谢! 原文链接:http://www.cnblogs.com/zishi/p/6766994.html 众所周知Sona ...

  7. 详解Android中的四大组件之一:Activity详解

    activity的生命周期 activity的四种状态 running:正在运行,处于活动状态,用户可以点击屏幕,是将activity处于栈顶的状态. paused:暂停,处于失去焦点的时候,处于pa ...

  8. 连接池中的maxIdle,MaxActive,maxWait等参数详解

    转: 连接池中的maxIdle,MaxActive,maxWait等参数详解 2017年06月03日 15:16:22 阿祥小王子 阅读数:6481   版权声明:本文为博主原创文章,未经博主允许不得 ...

  9. 【转载】3D/2D中的D3DXMatrixPerspectiveFovLH和D3DXMatrixOrthoLH投影函数详解

    原文:3D/2D中的D3DXMatrixPerspectiveFovLH和D3DXMatrixOrthoLH投影函数详解 3D中z值会影响屏幕坐标系到世界坐标系之间的转换,2D中Z值不会产生影响(而只 ...

  10. SQL Server中通用数据库角色权限的处理详解

    SQL Server中通用数据库角色权限的处理详解 前言 安全性是所有数据库管理系统的一个重要特征.理解安全性问题是理解数据库管理系统安全性机制的前提. 最近和同事在做数据库权限清理的事情,主要是删除 ...

随机推荐

  1. js String字符串对象常见方法总结

    String对象常用来保存文本形式的数据. 其转化方法有二种: String(s) new String(s) String对象方法有: charAt() charCodeAt() concat() ...

  2. <Android 应用 之路> MPAndroidChart~BarChart

    简介 MPAndroidChart是PhilJay大神给Android开发者带来的福利.MPAndroidChart是一个功能强大并且使用灵活的图表开源库,支持Android和IOS两种,这里我们暂时 ...

  3. Android Studio 2.3.2 下载 - 百度网盘

    Android Studio是一个为Android平台开发程序的集成开发环境,其包含用于构建Android应用所需的所有工具. Android Studio 2.3.2为最新的稳定版(截止到2017年 ...

  4. js 数据格式化

    //金额增加千分号formatPrice(123456.78) = 123,456.78 function formatPrice(val) { var parts = val.toString(). ...

  5. MVC的验证(模型注解和非侵入式脚本的结合使用)

    @HtmlHrlper方式创建的标签,会自动生成一些属性,其中一些属性就是关于验证 如图示例: 模型注解 通过模型注解后,MVC的验证,包括前台客户端,后台服务器的验证,MVC统统都做了包含,即使用户 ...

  6. ubuntu 16.04 virtualbox could not insert 'vboxdrv': Required key not available 问题解决方法

    从 内核版本 4.4.0-20 开始,在开启了 Secure Boot 的电脑上,未注册的 kernel 模块不再允许执行,所以如果想在保持 Secure Boot 的情况下依然允许执行,我们需要做的 ...

  7. Oracle基础操作

    数据库的定义.作用介绍: 什么是数据库? 按照数据结构来组织.存储和管理数据的建立在计算机存储设备上的仓库. 数据库的发展史: 起始于1962年,1968年在IBM出现 数据库在测试过程中的作用: 需 ...

  8. 奇葩拿shell + 提权wind08r2奇葩拿shell + 提权wind08r2戏

    0x01 小隐拿站篇 某省还是市级还是县级的空防部 先来刺探目录,拿起御剑, 啪啪啪  (鼓掌)后台出来了   试试弱口令 擦  需要管理员验证码,这个咋玩????这个注入都不用找了,就算注射出账号密 ...

  9. mongodb 副本集+分片集群搭建

    数据分片节点#192.168.114.26mongod --shardsvr --replSet rsguo --port 2011 --dbpath=/data/mongodb/guo --logp ...

  10. Ubuntu16.04更换NVIDIA驱动导致无法进入图形界面的解决方案

    一.进入recovery模式 由于无法进入图形界面,所以需要在开机时进入恢复模式.我的机器上时在开机时通过引导选项中的recovery mode选项进入,进入之后可以看到许多选项卡,选择root,回车 ...