对于iOS开发者来说,第一个要过的关大概就是iOS的内存管理吧。
那么我第一篇就从iOS的内存管理讲起:
iOS内存管理编程指南指出Objective-C提供了三种内存管理方式:
1.Manual Retain-Relaease
开发者使用由NSObject和Runtime共同提供的引用计数模型,自己用代码来管理内存。
2.Automatic Reference Counting
ARC 自动引用计数 和MRR一样同样采用引用计数,但是在编译时插入内存管理的方法。这里ARC自动地帮助我们处理了引用计数相关的内存操作。
3.Garbage Collection
垃圾回收。系统对于没有引用的对象,自动化回收处理。Mac OS下使用,iOS不可以。
无论是内存管理指南 还是 其他一些讲到有关iOS内存管理的书籍,都会提到内存管理的方式:
1.自己生成的对象自己拥有(以alloc/new/copy/mutableCopy来头的方法)
2.可以通过retain持有一个对象
3.不再需要一个对象时,要放弃对象的持有
4.使用中的对象不要进行release(引起crash)
ps:对于一些以alloc/new/copy/mutableCopy开头的方法却并不属于上面所说的情况,如:newer,copying,allocate等。对于一些能够得到对象,自己却不持有的例子如[NSMutableArray array],其实是使用autorelease 实现的。
autorelease的使用:
首先生成autopool 然后对象a调用autorelease把a对象放入autoPool中,autoPool调用drain相当于对pool内所有的对象进行release
ps:autopool对象不可以使用autorelease方法。
ARC:
__strong 修饰符
所有的对象前缀都默认加上了__strong;
__strong 修饰的变量在超出它的作用域的时候会自动释放,相当于调用了一次releease
就算是
因为是__strong强引用 也会变成自己持有。
ps:
__weak 修饰符
因为__strong会出现循环引用问题 所以引入了__weak修饰符
因为__weak修饰的变量持有对象的弱引用,生成的对象会被立即释放。
_unsafe_unretained
使用_unsafe_unretained修饰的对象不属于编译器的内存管理对象。
它和__weak修饰符一样都不持有对象,所以生成的对象会被立即释放。但是它和weak不同的是,在对象被释放时weak修饰的指针变量会被设置成nil 而 _unsafe_unretained不会。
__autoreleasing 修饰符
在写的时候我们很少会加上__autoreleasing修饰符
因为没有指定修饰符,所以默认是strong,因为return让变量超出了作用域,所以该强引用的对象会被释放,但是作为函数返回值编译器会自动把它加入到autoreleasepool。
ps:访问__weak修饰符的变量时,必定会访问注册到autoreleasepool的对象。__weak持有对象的弱引用,在访问过程中,对象可能被废弃。所以会把对象注册到autoreleasepool中,保证在autoreleasepool结束之前都可以确保对象存在。
ps: id *类型 默认修饰符是 __autoreleasing
ps:需要注意的是在ARC环境中要显式转换id和void *
这时可以使用__bridge
__bridge有两种__bridge_retained和__bridge_transfer
__bridge_retained 这种转换让a和p和b同时持有该对象
__bridge_transfer这种变换先让p持有对象 释放a 然后让b持有对象释放p
通常用来于CF之间的转换。