iOS 學習日誌(5) -----ARC中的_bridge

因爲ARC不能管理Core Foundation Object的生命週期,因此當咱們在Object-C 和 Core Foundation對象之間轉換(id 與 void* 之間的轉換)時,咱們須要使用到__bridge,__bridge_retained和__bridge_transfer三個轉換關鍵字。app

_bridge:只作類型轉換,可是不修改對象(內存)全部權。例如:spa

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 )例如:code

/* 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:ip

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);
}
相關文章
相關標籤/搜索