因爲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); }