4-6 ARC以及修饰符

修饰符

nonatomic  atomic
strong  weak  retain copy
readonly readwrite 

atomic 是绝对的线程安全吗?

      atomic 只是在get set 方法内部添加了锁 只保证set get 的线程安全保证读写的安全性 就是保证返回一个正常的对象 
   如果一个数据占的内存特别大,读写这块数据需要的时间也就越长,如果这个时间长度远远超过线程调度的轮询片,那么就有极大可能出现并发问题。单单这样说其实还是不能归纳那些数据才会出现并发问题
            首先第一点,你要记住,@property(atomic)NSArray *array 其实修饰的是这个指针,也就是这个8字节内存,跟第二部分数据n字节没有任何关系,被atomic 修饰之后,你不可能随意去多线程操作这个8字节,但是对8字节里面所指向的n字节没有任何限制!这就是所有网络上所说的 atomic 不安全的真想 
            现在我们有一个8字节的指针,假如我们做一个初始化 NSArray *array = [[NSArray alloc] init] 这个操作。实际上这个操作有两个意思
1:给8字节赋值
2:开辟了一块n字节的内存区

我们只说这8自己的地址复制,如果没有atomic 修饰,并且假设现在有两个线程正在操作这个指针,一个就是上面的初始化线程,另一个线程就是读这个8自己的指针

首先,假如8字节内部存放的是0x1122334455667788  ok 8字节需要写入这个指,但与此同时,很不巧,另一个读线程现在要读这个8字节里面的值

假如 这个8字节只写了一半的时候 另一个线程来读,那它读到的可能是 0x1122334400000000 OK 实际上,等他读完之后,写线程仍然还未完成

这时候,[[NSArray alloc] init] 的头地址正确的应该是0x1122334455667788 ,而读线程读到的是0x1122334400000000  这时候会出现什么情况?

最好的情况,无非就是个野指针,因为谁也不知道这块地址是否有效或者是否有什么重要的数据,也指针会导致啥不多说了
最坏的情况,这个野地址指向的是重要的一段数据。。。后果可想而知。

所以 atomic 的意义就在于此,在0x1122334455667788 写完之前,读线程是无法读取的,同样的道理,在读线程正在读的过程中,写线程是无法改变8字节的
            atomic 能避免这8字节的值因为多线程的原因被意外破坏,仅此而已
            atomic 只是保证 指针的安全性  通过atomic 我们可以保证这个“指针”被有序的访问。但是对指向的内容 不保证安全
             automic 只保护它修饰的那个变量。
在实际使用的时候,需要同步的变量往往不止一个,所以 automic 基本没啥用
不保证1.数据的并发性 比如窗口买票的问题
            2.不保证数组 addObject

retain实现原理

通过SideTables这个数据结构来存储引用计数
SideTables 是由多个SideTable来实现的
retain  通过两次hash查找 找到数量  然后对应的引用计数加1,

release实现原理

release的到这里也比较清楚了:查找map,对引用计数减1,如果引用计数小于阈值,则调用SEL_dealloc

dealloc 实现原理

dealloc 
1.判断是否是nonpointer——isa指针
2.判断是否有weak修饰
3.是否有关联对象
4.是否有C函数
5.引用计数是否在散列表里面

面试题:通过关联对象的方式添加 是否需要我们手动去释放对象

1.不需要  系统会帮我们自己判断 然后释放掉

第一个讲解了 alloc retain release实现原理
深入理解Objective C的ARC机制
Objective-C类成员变量深度剖析

你可能感兴趣的:(4-6 ARC以及修饰符)