Objective-C引用计数有两种方式:

  1. 使用默认的自动引用计数 Automatic Reference Counting(ARC)方式,通过属性(@property:strong,weak)或变量(variable:__weak)的修饰符,让编译器自动完成引用计数管理的工作。
  2. 在ARC出现之前,需要手动管理引用计数,所以很多历史的老工程都还是使用了手动管理的方式。

两种方式的使用,在objc的语法上都有些差异,后面详细解析两种方式的使用和注意点。

引用计数管理的基本原则:

手动管理引用计数 Manual Retain-Release(MRR)

@property & @synthesize 声明属性的引用类型

消息类型

- (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 相关的类型转换关键字:

Reference

Encapsulating Data

Memory Management Policy

Practical Memory Management

Toll-Free Bridged Types