国内最全IT社区平台 联系我们 | 收藏本站
华晨云阿里云优惠2
您当前位置:首页 > php开源 > 综合技术 > __bridge_retained/__bridge_transfer/__bridge使用详解

__bridge_retained/__bridge_transfer/__bridge使用详解

来源:程序员人生   发布时间:2014-12-12 08:33:08 阅读次数:5045次
第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;





生活不易,码农辛苦
如果您觉得本网站对您的学习有所帮助,可以手机扫描二维码进行捐赠
程序员人生
------分隔线----------------------------
分享到:
------分隔线----------------------------
关闭
程序员人生