首页 > 代码库 > __bridge_retained/__bridge_transfer/__bridge使用详解
__bridge_retained/__bridge_transfer/__bridge使用详解
第一、__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
分析:
当想把本来拥有对象所有权的变量,在类型转换后,让其释放原先所有权的时候,需要使用 __bridge_transfer 关键字。
如在非ARC环境下:
id obj = (id)p;
[obj retain];
[(id)p release];
在ARC环境下,使用__bridge_transfer,如下所示:
id obj = (__bridge_transfer id)p;
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\n",CFGetRetainCount(cfObject));
}
printf("the retain count is %ld\n",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\n",CFGetRetainCount(cfObject));
}
//printf("the retain count is %ld\n",CFGetRetainCount(cfObject));
CFRelease(cfObject);
}
CFRelease(cfObject);会抛异常,__bridge实现了转换,并没有保持对象。
3、使用__bridge_transfer
@autoreleasepool {
CFMutableArrayRef cfObject=CFArrayCreateMutable(kCFAllocatorDefault, 0, NULL);
printf("the retaincount is %ld\n",CFGetRetainCount(cfObject));
/*
* __bridge_transfer,对cfObject执行release操作,然后将对象赋给了obj,但是cfObject仍然指向存在的对象,可以正常使用
*/
id obj=(__bridge_transfer id)cfObject;
printf("after __bridge_transfer retaincount is %ld\n",CFGetRetainCount(cfObject));
NSLog(@"class=%@",obj);
}
/*
*obj跳出作用域,强引用失效,释放对象,没有内存泄露
*/
return 0;
__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看上去处于持有该对象的状态,因此该对象不会被释放
当想把本来拥有对象所有权的变量,在类型转换后,让其释放原先所有权的时候,需要使用 __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
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\n",CFGetRetainCount(cfObject));
}
printf("the retain count is %ld\n",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\n",CFGetRetainCount(cfObject));
}
//printf("the retain count is %ld\n",CFGetRetainCount(cfObject));
CFRelease(cfObject);
}
CFRelease(cfObject);会抛异常,__bridge实现了转换,并没有保持对象。
3、使用__bridge_transfer
@autoreleasepool {
CFMutableArrayRef cfObject=CFArrayCreateMutable(kCFAllocatorDefault, 0, NULL);
printf("the retaincount is %ld\n",CFGetRetainCount(cfObject));
/*
* __bridge_transfer,对cfObject执行release操作,然后将对象赋给了obj,但是cfObject仍然指向存在的对象,可以正常使用
*/
id obj=(__bridge_transfer id)cfObject;
printf("after __bridge_transfer retaincount is %ld\n",CFGetRetainCount(cfObject));
NSLog(@"class=%@",obj);
}
/*
*obj跳出作用域,强引用失效,释放对象,没有内存泄露
*/
return 0;
__bridge_retained/__bridge_transfer/__bridge使用详解
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。