__bridge_retained/__bridge_transfer/__bridge使用詳解
來源:程序員人生 發布時間:2014-12-12 08:33:08 閱讀次數:5167次
第1、__bridge_retained的使用
__bridge_retained轉換可以使要轉換的變量也持有所賦值的對象
void *p=0;
{
id obj=[[NSObject alloc] init];
p=(__bridge_retained void*)obj;
}
NSLog(@"class=%@",[(__bridge id)p class]);
輸出結果:
class=NSObject
分析:
變量作用域結束后,雖然obj失效,__bridge_retained轉換使變量p看上去處于持有該對象的狀態,因此該對象不會被釋放
第2、__bridge_transfer
當想把本來具有對象所有權的變量,在類型轉換后,讓其釋放本來所有權的時候,需要使用 __bridge_transfer 關鍵字。
如在非ARC環境下:
id obj = (id)p;
[obj retain];
[(id)p release];
在ARC環境下,使用__bridge_transfer,以下所示:
id obj = (__bridge_transfer id)p;
__bridge_retained是編譯器為我們做了retain操作,__bridge_transfer是編譯器為我們做了release
第3、在 Core Foundation框架中的使用
CoreFoundation對象是用C語言實現CoreFoundation Framework的對象,也有援用計數的概念,使用的關鍵詞是CGRetain/CFRelease,
由于和Foundation結構相同,在非ARC下可以用C語言的類型轉換,以下所示:
NSString *str=@"RichardYang";
CFStringRef strRef=(CFStringRef)str;
在ARC環境下,由于編譯器會管理Foundation對象的內存,但CoreFoundation對象卻不會處理,此時,使用關鍵詞__bridge/__bridge_retained進行處理。
1、使用__bridge_retained
@autoreleasepool {
CFMutableArrayRef cfObject=nil;
{
id obj=[[NSMutableArray alloc] init];
cfObject=(__bridge_retained CFMutableArrayRef)obj;
//CFShow(cfObject);
printf("the retain count =%ld
",CFGetRetainCount(cfObject));
}
printf("the retain count is %ld
",CFGetRetainCount(cfObject));
CFRelease(cfObject);//如果不履行CFRelease則內存泄漏
}
輸出結果為:
the retain count =2
the retain count is 1
2.使用__bridge
只做類型轉換,但是不修改對象(內存)管理權;
@autoreleasepool {
CFMutableArrayRef cfObject=nil;
{
id obj=[[NSMutableArray alloc] init];
cfObject=(__bridge CFMutableArrayRef)obj;
//CFShow(cfObject);
printf("the retain count =%ld
",CFGetRetainCount(cfObject));
}
//printf("the retain count is %ld
",CFGetRetainCount(cfObject));
CFRelease(cfObject);
}
CFRelease(cfObject);會拋異常,__bridge實現了轉換,并沒有保持對象。
3、使用__bridge_transfer
@autoreleasepool {
CFMutableArrayRef cfObject=CFArrayCreateMutable(kCFAllocatorDefault, 0, NULL);
printf("the retaincount is %ld
",CFGetRetainCount(cfObject));
/*
* __bridge_transfer,對cfObject履行release操作,然后將對象賦給了obj,但是cfObject依然指向存在的對象,可以正常使用
*/
id obj=(__bridge_transfer id)cfObject;
printf("after __bridge_transfer retaincount is %ld
",CFGetRetainCount(cfObject));
NSLog(@"class=%@",obj);
}
/*
*obj跳出作用域,強援用失效,釋放對象,沒有內存泄漏
*/
return 0;
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈