iOS 学习日志(5) -----ARC中的_bridge

由于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);
}

你可能感兴趣的:(iOS 学习日志(5) -----ARC中的_bridge)