Objective-C引用计数有两种方式:
- 使用默认的自动引用计数
Automatic Reference Counting(ARC)
方式,通过属性(@property:strong,weak)或变量(variable:__weak)的修饰符,让编译器自动完成引用计数管理的工作。 - 在ARC出现之前,需要手动管理引用计数,所以很多历史的老工程都还是使用了手动管理的方式。
两种方式的使用,在objc的语法上都有些差异,后面详细解析两种方式的使用和注意点。
引用计数管理的基本原则:
- 你拥有你创建的对象:创建对象的方法名以 “alloc”, “new”, “copy”, or “mutableCopy”开头
- 可以通过retain来持有对象的所有权
- 当所拥有的对象不需要时,需要释放所有权:发送release或autorelease消息
- 不是你所拥有的对象,不能去释放所有权
手动管理引用计数 Manual Retain-Release(MRR)
@property & @synthesize
声明属性的引用类型
- retain:持有引用计数
- copy:拷贝对象,并持有引用计数
- assign
消息类型
- retain:增加引用计数
- release:减少引用计数
- autorelease:返回对象常常用自动autorelease释放的对象
- (NSString *)fullName {
NSString *string = [[[NSString alloc] initWithFormat:@"%@ %@",
self.firstName, self.lastName] autorelease];
return string;
}
初始化和反初始化注意点
init:初始化
dealloc:特别是有retain对象的,需要在dealloc中release
注意:dealloc不要用来释放稀有资源,因为该方法的调用可能会被延迟
自动引用计数 Automatic Reference Counting(ARC)
@property
声明属性的引用类型
- strong
- 会持有引用计数,并且是默认的,所以不需要显式的指定
- weak
- 使用弱引用计数,不持有对象强引用,并且当对象消失时,会自动设为nil
- unsafe_unretained
- 有些类型还不支持weak修饰,这时需要弱引用计数的话,只能使用unsafe_unretained,与weak的差异在于对象消失时不会自动设为nil,比如NSTextView, NSFont 和 NSColorSpace等。
直接申明属性 或 变量的类型
在没有开启ARC的时候,不支持变量声明。
__strong
由于对象变量声明默认是__strong的,所以不需要显式指定
__weak
弱引用
弱引用用于闭包block的惯用法
__weak typeof(self) bSelf = self;
[webview registerEvent:eventType eventHandler:^(WebviewEventArgs *args) {
[bSelf doSomething];
}];
__unsafe_unretained
关于void*
与objective-c对象指针(id)的转型
ARC开启后,void*
无法与id类型直接转型,需要借助于__bridge
来实现相互转型。
id obj = [[NSObject alloc] init];
void *p = (__bridge void *)obj;
id o = (__bridge id)p;
将Objective-C的对象类型用bridge 转换为 void*
类型和使用unsafe_unretained关键字修饰的变量是一样的。被代入对象的所有者需要自己管理对象生命周期。
除了__bridge 以外,还有两个 __bridge 相关的类型转换关键字:
__bridge_transfer
: 类型被转换时,其对象的所有权也将被变换后变量所持有__bridge_retained
: 把本来拥有对象所有权的变量,在类型转换后,让其释放原先所有权