由于ARC不能管理Core Foundation Object的生命周期,所以当我们在Object-C 和 Core Foundation对象之间转换(id 与 void* 之间的转换)时,我们需要使用到__bridge,__bridge_retained和__bridge_transfer三个转换关键字。
_bridge:只做类型转换,但是不修改对象(内存)所有权。例如:
CFMutableArrayRef cfObject = NULL;
{
id obj = [[NSMutableArray alloc] init]; // obj has a strong reference to the object
cfObject = (__bridge CFMutableArrayRef)obj; // __bridge does not touch ownership status
CFShow(cfObject);
printf("retain count = %d\n", CFGetRetainCount(cfObject));
}
CFRelease(cfObject);
输出结果是retain count = 1
_bridge_retained(CFBridgingRetain):将Objective-C的对象转换成Core Fundation的对象,同时获得对象所有权,后续使用CFRealease或其他方法释放对象。(_bridge_retained cast works as if the assigned variable has ownership of the object )例如:
/* ARC */
id obj = [[NSObject alloc] init];
void *p = (__bridge_retained void *)obj;
/* non - ARC */
id obj = [[NSObject alloc] init]
void *p = obj;
[(id)p retain];
在ARC中,_bridge_retained 代替了retain,上面的obj与p 都拥有对象的所有权。再如:
/* ARC */
void *p = 0;
{
id obj = [[NSObject alloc] init];
p = (_bridge_retained void*)obj;
}
NSLog(@"class = %@",[(_bridge id)p class]);
上面的代码是有输出的。在大括号结束后,obj的所有权是已经释放了,但是p依然拥有对象的所有权,对象不会释放。
/* non-ARC */
void *p = 0;
{
id obj = [[NSObject alloc] init]; //obj 的retainCount 为1
p = [obj retain]; // obj 的retainCount 为2
[obj release]; // obj 的retainCount 为1
/*[(id)p retainCount] 为1,所有对象是依然存在的 */
}
NSLog(@"class = %@",[(_bridge id)p class]);
CFBridgingRetain:
CFBridgingRetain的实现方法:
CFTypeRef CFBridgingRetain(id X) {
return (__bridge_retained CFTypeRef)X;
}
例子:
CFMutableArrayRef cfObject = NULL;
{
id obj = [[NSMutableArray alloc] init]; // obj has a strong reference to the object
cfObject = CFBridgingRetain(obj); // the object is assigned to cfObject
CFShow(cfObject);
printf("retain count = %d\n", CFGetRetainCount(cfObject));
}
printf("retain count after the scope = %d\n", CFGetRetainCount(cfObject));
CFRelease(cfObject); // the object is discarded
输出结果是:
retain count = 2;//One is for strong reference of variable obj,the other is by CFBridgingRetain
retain count after the scope = 1;//leaving the scope strong reference disappears
_bridge_transfer(CFBridgingRelease):当想把本来拥有对象所有权的变量,在类型转换后,让其释放原先所有权的时候(__bridge_transfer cast will release the object just after the assignment is done )
/* ARC */
id obj = (__bridge_transfer id)p;
/* non-ARC */
id obj = (id)p;
[obj retain];
[(id)p release];
CFBridgingRelease:
CFBridgingRelease的实现方法:
id CFBridgingRelease(CFTypeRef X) {
return (__bridge_transfer id)X;
}
例子:
{
CFMutableArrayRef cfObject = CFArrayCreateMutable(kCFAllocatorDefault, 0, NULL);
printf("retain count = %d\n", CFGetRetainCount(cfObject));
id obj = CFBridgingRelease(cfObject);
printf("retain count after the cast = %d\n", CFGetRetainCount(cfObject));
NSLog(@"class=%@", obj);
}