iOS关于property中的atomic和nonatomic

首先这两个属性特质是为了处理多线程安全问题,那么什么是多线程安全,多线程安全就是多个线程访问同一段代码、指针区域、内存区域的时候出现的异常不安全情况。首先,我们要知道内存的访问时串行的,并不会导致内存数据的错乱或者应用的crash,以及读写的内存长度小于等于地址总线的长度,那么读写的操作是原子的,一次完成。例如BOOL,int,long在64位系统下的单次读写都是原子操作,无需担心线程安全问题。那么atomic主要有什么用呢?atomic主要针对getter和setter方法做原子操作,保证getter和setter方法可以顺序执行。如果不加atomic会怎么样呢?当内存长度大于地址总线的时候,例如在64位系统下内存中读取无法像bool等纯量类型原子性完成,可能会在读取的时候发生写入,从造成异常情况。atomic还会使用memory barrier能够保证内存操作的顺序,按照我们代码的书写顺序来。面试官经常会问,为什么atomic不是绝对安全的?我总结了一些有一下几点:1、atomic的作用只是给getter和setter加了个锁,atomic只能保证代码进入getter或者setter函数内部时是安全的,一旦出了getter和setter,那么外面的代码可能会造成线程不安全问题,而且还会造成性能上的损耗,这就是为什么我们经常说使用nonatomic就可以了。2、一般property属性变量里面存的是地址,虽然MRC里面会setter和getter方法会生成保留释放设置值的操作代码,但是ARC中都是自动管理无需担心属性变量变成无效的地址空间,所以只是简单的做读写操作atomic和nonatomic没有区别。但是在访问属性变量的内存区域的时候,如果不手动设置线程安全代码会出现问题,比如调用NSString对象的length、substringWithRange等方法就是在访问内存区域,当多线程访问内存区域发生变化的时候,就会出现异常情况。这时候需要自己写代码加锁,保证线程安全。

通关上面的内容总结就是,我们开发中用nonatomic就可以了,想保证线程安全,要自己手动写一些线程安全的代码,比如利用NSLock、同步锁、GCD的窜行队列、并发队列和栅栏块等。

你可能感兴趣的:(iOS,iOS性能优化,iOS多线程)