iOS之__bridge / __bridge_retained / __bridge_transfer

__bridge, __bridge_retianed__bridge_transfer用来处理OC对象和CF对象的转换。

转换规则:

  • __bridge:只转换对象类型,不涉及对象所有权的转换(不增加对象引用计数);容易造成悬垂指针。
    • 悬垂指针:指针指向的内存已经被释放;
    • 野指针:没有被正确初始化的指针,指向内存中随机的位置;
  • __bridge_retained:OC对象转换成CF对象,OC对象所有权交给CF对象(CF指针也会持有对象),CF对象需要自己管理内存。
  • __bridge_transfer:CF对象转换成OC对象,将CF对象所有权交给OC对象(CF指针不再持有对象),ARC自动管理内存。

ARC环境下编译器会自动管理OC对象的内存,但是不会自动管理CF对象的内存。

CF对象需要手动释放。

__bridge示例:

1
2
3
4
5
6
7
id obj = [[NSObject alloc] init];

// OC转CF pointer指针不持有对象,不会增加obj的引用计数
void *pointer = (__bridge void *)(obj);

// CF转OC
obj = (__bridge id)(pointer);

__bridge_retained示例:

1
2
3
4
5
6
7
void *pointer = NULL;
{
id obj = [[NSObject alloc] init];
// pointer会引用obj对象
pointer = (__bridge_retained void *)obj;
}
NSLog(@"retain count:%ld", CFGetRetainCount((__bridge CFTypeRef)((__bridge id)pointer))); //retain count:1

__bridge_transfer示例:

1
2
3
4
5
6
7
void *pointer = NULL;
{
id obj = [[NSObject alloc] init];
pointer = (__bridge_retained void *)obj;
}
//pointer持有对象
id object = (__bridge_transfer id)pointer;