内存管理之 ARC 和 自动释放池
一、ARC 中的变量所有权修饰符
变量修饰符,主要用来标识对象的生命周期.在手动内存管理方式中没有这些概念.
ARC 环境下变量所有权修饰符主要有以下几个:
__strong
__weak
__unsa_unretained
__autoreleasing
详细说明:
(1) 变量默认值都是__ strong 修饰
只要强引用存在,对象就不能释放.当超过了对象的作用域以及没有强引用时,对象会自动销毁.
_strong 属性基本上能适应 ARC 环境下的所有情况.如果不写的话,默认为_ strong 属性.
(2) __weak 不持有对象,只是简单地引用而已.
也就是说,_weak不会影响对象的销毁,只要__weak 修饰的对象没有强引用时,就会自动销毁,这时候_ weak 变量会自动设置成 nil.
下面是一个例子
NSString *__weak str = [][NSString alloc] initWithFormat:@"I am studying"];
NSLog (@"str : %@",str);
因为 str 这个对象是弱引用,编译器会提示,这是一个弱引用,输出的结果: str:null
在你打开ARC时,你是不能使用retainrelease autorelease 操作的,原先需要手动添加的用来处理内存管理的引用计数的代码可以自动地由编译器完成了,但是你需要在对象属性上使用weak 和strong, 其中strong就相当于retain属性,而weak相当于assign,基础类型还是使用assign。
二、自动释放池
- 自动释放池是一个存放实体的集合,这些实体可能是对象,这些对象能够被自动释放.
- (id)autorelease;// 是 NSObject提供的方法,此方法在某一个预定的时候,想对象发送 release 消息,返回值是接收消息的对象.实际上当给一个对象发送 autorelease 消息的时候,就是将这个对象添加到自动释放池( NSAutoreleasePool) 中,当自动释放池被销毁时,会向该池中的所有对象发送 release 消息
临时对象和拥有对象
当使用如:arrayWithCapacity这样的方法获取临时对象的时候,你不必考虑内存释放问题。
[NSColor blueColor]; 单例对象,永远不会被销毁,但是你也不必考虑它的内存问题。
如果在你自定义的类中依赖其它对象时,你需要重写dealloc方法,并且在这个方法中释放依赖的对象
如果在设计的循环体中会占用较多的内存空间,建议手动创建自动释放池。如:
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
for ( int i = 0; i < 1000000; i++) {
id object = [someArray objectAtIndex:i];
NSString *desc = [object description];
// and do something with te descripton
if ( i % 100 == 0) {
[pool release];
pool = [[NSAutoreleasePool alloc] init];
}
}
APC 的本质
- ARC 本质上是由编译器在编译阶段,在合适的地方插入 retain 和 release 方法.
- ARC 是编译时的特性.
关于 ROP 和 non-ROP
所有权归属问题
NSString *theString = @"Hello,Henan";
CFStringRef cfString = (CFStringRef)theString
// __bridge
cfString = (__bridge CFStringRef)theString //指针的所有权不变,所以是 theString
// __bridge_retained
cfString = (__bridge_retained CFStringRef)theString// 指针的所有权对象是 cfString
// __bridge_transfer
cfString = (__bridge_transfer CFStringRef)theString// 指针的所有权属于 theString
使用 ARC 的一些强制规定
- 不能直接调用 dealloc 方法,不能调用 retain,release,autorelease,retainCount 方法,包括@ selector(retain) 的方法也不行.
- 如果你需要管理资源而不是释放实例变量,你应该事先 dealloc 方法.不能再 dealloc 方法里面去调[ super dealloc] 方法,在 ARC下父类的 dealloc 同样由编译器来自动完成.
- Core Foundation 类型的对象仍然可以用 CFRetain,CFRealese 这些方法.
- 不能在使用 NSAllocateObject和 NSDeallocateObject 对象.
- 不能在 C 结构中使用对象指针,如果有类似功能,可以创建一个 Objective-C 类来管理这些对象
- 在 id和 void * 之间没有简便的转换方法,同样在Objective-C 和 Core Foundation 类型之间的转换都需要使用编译器指定的转换函数.
- 不能再使用 NSAutoreleasePool 对象, ARC 提供了@ autoreleasepool 块来替代它,这样更加有效率.
- 不能使用内存储存区(不能再使用 NSZone)
- 不能以 new 为开头给一个属性命名.
- 声明 outlet 时一般使用 weak, 除了对 StoryBoard 这样的 nib 中间的顶层对象要用 strong.
- weak 相当于老版本的 assign,strong 相当于 retain.
版权声明:本文为博主原创文章,未经博主允许不得转载。
时间: 2024-08-08 05:39:04