iOS关于内存管理的那点事儿

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xiaozhuanddapang/article/details/79761902

iOS内存管理

iOS内存管理从整体来讲,就四点:
①自己生成的对象,自己持有;
②非自己生成的对象,自己也能持有;
③不再需要自己持有的对象时释放;
④非自己持有的对象无法释放。

MRC下的内存管理

在进行MRC内存管理时,我们需要注意几点:
①自己生成的对象,自己持有,比如new/alloc/copy/mutableCopy创建;
②非自己生成的对象,自己也能持有,比如retain持有;
③不再需要自己持有的对象时释放,用release释放;
④非自己持有的对象无法释放,比如对象release以后已经释放,再次release会引起崩溃。

ARC下的内存管理

在进行ARC内存管理时,我们需要注意几点:
①block中循环引用问题;
②CoreFoundation和Foundation框架桥接转换;
③手动开辟的内存需要自己释放;
④在类中,dealloc方法中对KVO和Notification置为nil。
⑤不能显示的调用retain、release、dealloc方法
⑥使用自动释放池时,用@autoreleasepool块来代替NSAutoreleasePool对象。
⑦由于ARC中内存管理是由编译器来做的,而C语言中没有方法来管理结构体成员的生命周期,所以OC中的变量不能作为C语言结构体的成员。
⑧在MRC中可以显示的转换id和void *,但是在ARC中需要通过__bridge进行桥接转换。

从所有权修饰符来看

内存管理中的所有权修饰符分为四种:
__strong、__weak、__autorelease、__unsafe_unretained。前三个所有权修饰符可以保证初始化为nil,最后一个所有权修饰符不能自动置为nil。

①__strong修饰符是id类型和对象类型默认的修饰符,__strong修饰符的引入,解决了MRC中需要手动release来解决内存管理问题。

②__weak修饰符用来打破循环引用,造成循环引用的情况有两种,一种是对象间互相强引用,一种是对象对自身的强引用。

③__weak用于iOS5以后打破循环引用,iOS5之前使用__unsafe_unretained来打破循环引用,在ARC中使用__unsafe_unretained时,该修饰符所修饰的对象,其内存不属于编译器的管理范围。

④__unsafe_unretained修饰对象时,必须保证该对象没有废弃,否则可能引起崩溃。

__strong所有权修饰符和__weak所有权修饰符

__strong所有权修饰符:
①通过alloc初始化,伪代码实现
id obj = objc_msgSend(obj, @selector(alloc));
obj_msgSend(obj, @selector(init));
obj_release(obj);
②通过类方法初始化,伪代码实现
id obj = objc_msgSend(NSMutableArray, @selector(array));
objc_retainAutoreleasedReturnValue(obj);
objc_release(obj);

__weak所有权修饰符:
第一点:附有__weak修饰符的变量所引起的对象被废弃,则将nil赋值给该变量。
id __weak obj1 = obj;
上面代码,通过伪代码实现
id obj1;
objc_initWeak(&obj1,obj);
objc_destoryWeak(&obj1);
定义函数objc_storeWeak,把第二个参数的赋值对象的地址作为键值,将第一个参数的附有__weak修饰符的变量的地址注册到weak表中,如果第二个参数为0,则把变量的地址从weak表中删除。
以上伪代码,也可通过以下伪代码实现
id obj1 = 1;
objc_storeWeak(&obj1,obj);
objc_storeWeak(&obj1,0);
weak表与引用计数表相同,都是作为散列表被实现。如果使用weak表,将废弃对象的地址作为键值进行检索,就能高速的获取对应的附有__weak修饰符的变量地址。另外,由于一个对象可同时赋值给多个附有__weak修饰符的变量中,所以一个键值,可注册多个变量的地址。
释放weak修饰的对象时,程序的执行步骤分为四步:
①从weak表中获取废弃对象的地址为键值的记录;
②将包含在记录中的所有附有__weak修饰符变量的地址,赋值为nil;
③从weak表中删除该记录;
④从引用计数表中删除废弃对象的地址为键值的记录。

第二点:附有__weak修饰符的变量,即是使用注册到autoreleasepool中的对象
id __weak obj1 = obj;
NSLog(@“%@”,obj1);
上面代码通过伪代码实现
声明两个函数,objc_loadWeakRetained函数取出附有__weak修饰符变量所引用的对象并retain,objc_autorelease函数将对象注册到自动释放池中。
id obj1;
objc_initWeak(&obj1,obj);
id tmp = objc_loadWeakRetaind(&obj1);
objc_autorelease(tmp);
NSLog(@“%@”,tmp);
objc_destoryWeak(&obj1);

属性修饰符中的所有权修饰符

属性修饰符中,assgin和unsafe_unretained的所有权修饰符是__unsafe_unretained、strong和retain、copy的所有权修饰符是__strong,weak的所有权修饰符是__weak。

猜你喜欢

转载自blog.csdn.net/xiaozhuanddapang/article/details/79761902
今日推荐