weak、assign、strong、copy、mutableC

2018-09-06  本文已影响0人  稻草人娃娃

weak:不会引起引用计数增加,并且在对象释放后会自动把指针置nil

Runtime维护了一个weak表(hasn散列表),用于存储指向某个对象的所有weak指针,该散列表的可以为所指对象的地址,value为指向当前对象所有weak修饰变量指针的数组

id obj =[ [NSObject alloc]init]; (OC中未指定修饰符的对象默认__strong修饰)

id __weak obj1 = obj (把当前赋值给__weak修饰的对象)

内部:runtime调用init_weak()函数,把赋值对象地址最为键值传入,把__weak修饰的变量的地址指针作为value传入,初始化__weak指针;

init_weak(&obj1, obj)

然后init_store()内部调用store_weak()函数为把上面的两个值传入,更新当前指针指向,创建新的弱引用表,调用过程简化版图如下

store_weak(&obj1, obj);

weak_entry_t结构体维护和存储指向一个对象的所有弱引用hash表

weak对象自动置nil原理:

        当__weak修饰变量指针指向的对象引用计数为0时,系统会释放掉该对象,调用clearDeallocating 通过obj对象地址找到对应的弱引用表,并遍历array中的所有weak指针依次置nil后,删除当前地址所对应的entry(弱引用表)

模拟hash表中对象对应的弱引用表

假设有__weak 修饰的a、b、c、d、......指针变量都指向obj对象,那么对应的弱引用表如下

参考来自

iOS 底层解析weak的实现原理(包含weak对象的初始化,引用,释放的分析) - 简书


assign:一般修饰基本类型,不会引起引用计数增加,被修饰对象存储在栈区,系统自动管理内存的释放,不用开发者手动管理内存,但在assign修饰对象类型变量时,被修饰对象释放后,与weak的区别就在于当引用对象呗释放掉后,不会自动删除内存中的地址的内容并把指针变量置nil,会造成野指针,也就是说当前对象引用对象被释放掉后,再使用该对象时或再使用当前对象指向的内存地址时,会造成crash

        栈区创建对象的特点就是对象随时会被销毁,再调用当前引用对象时就会造成崩溃


stong:强引用类型,修饰的对象会引起retainCount+1,默认情况下,所有实例变量和局部变量都是strong类型的;

strong类型变量指针会指向赋值对象,所以在对赋值对象做修改是,会影响被赋值对象的值

在修饰block时,strong与copy相似,都会把block放入栈区,由于MRC下生成的block都是在栈区,需要用copy方法把block拷贝到堆区,所以现在ARC下沿用了之前的传统,block也用copy修饰,其实用其他修饰符也可以,但是用weak/assign修饰block会出现提前释放的问题,造成崩溃;


copy&mutableCopy(NSString/NSMutableString/NSArray/NSMutableArray/NSDictionary/NSMutableDictionary):

首先我们要弄懂两个概念:

1、浅复制:不拷贝对象本身,只拷贝指向对象的指针(对象指针指向当前对象),一般‘=’赋值的对象都是shallow copy

2、深复制:在内存中开辟一块新的地址,把当前对象copy进去

接下来来说一下copy关键字的特点:赋值对象与被赋值对象相互独立,互不影响,各自修改操作也不会对对方有影响

copy:创建的是不可变副本(NSString,NSArray,NSDictionary)

1、当一个不可变得对象执行copy操作时,新对象的地址与旧对象完全相同,由于old对象不可变,所以copy的new对象也是不可修改的,两个对象永远不会影响到另一个对象,所以为了节省内存,不会产生新的对象(NSString,NSArray,NSDictionary)  ———— shallow copy,执行copy操作都是这一道理;

2、浅拷贝因为不会产生新的对象,系统会对原对象进行retain

3、当一个可变对象(NSMutableString,NSMutableArray,NSMutableDictionary)执行copy操作时,new对象会生成一个不可变得对象,不可修改,所以会分配一块新的内存,———— deep copy

mutableCopy:创建的是可变副本(NSMutableString,NSMutableArray,NSMutableDictionary),无论是可变对象还是不可变对象执行mutableCopy操作,都会生成一个新的对象———— deep Copy

图片来源于网络

weak、assign、strong、copy最大的区别就在于

1、是否增加引用计数

2、是否开辟新的内存

上一篇下一篇

猜你喜欢

热点阅读