处理CF和OC对象的转化的三个修饰符

本文介绍了在ARC环境下,处理CoreFoundation(CF)对象与Objective-C(OC)对象转化时的三个修饰符:__bridge、__bridge_retain和__bridge_transfer。__bridge用于编译需求,确保CF与OC对象之间的转化;__bridge_retain防止野指针,通过retain操作保持对象生命周期;__bridge_transfer则用于防止内存泄漏,自动释放CF对象并转移所有权给OC对象。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

CF( CoreFoundation)是一套c语言的api,用于面向Objective-C基础数据和服务的管理和维护。

在开启ARC环境下,处理CF对象和OC对象的转化的三个修饰符包括:__bridge, __bridge_transfer, __bridge_retain

1、为什么需要__bridge?

成功编译的需要。

id obj = [[NSObject alloc] init];
void *pObj = obj; 

此时编译会报错:Implicit conversion of Objective-C pointer type 'id' to C pointer type 'void *' requires a bridged cast

同样的:

void *pTr = 0;
id newObj = pTr;
编译也会报错:Implicit conversion of C pointer type 'void *' to Objective-C pointer type 'id' requires a bridged cast

也就是说CF对象和OC对象之间,在ARC环境下转化需要bridged cast

上面的实例,只要这么改编译就可以通过了:

id obj = [[NSObject alloc] init];
void *pObj = (__bridge void *) obj;
void *pTr = 0 ;
id newObj = (__bridge id)pTr;


2、为什么需要__bridge_retain ?

防止出现野指针。

看下这个场景:

void *pTr = 0;
{
   id anotherObj = [[ViewController alloc] init];
   pTr = (__bridge void *)anotherObj; (#)
}
NSLog(@"pTr points class = %@", [(__bridge id)pTr class]); (*)
编译时没有问题的,但是在运行的时候,(*) 会出现必现崩溃:EXC_BAC_ACCESS

我们知道野指针的出现,是这个指针所引用的内存被释放,而这个指针没有置nil(NULL)导致的。

作为局部对象anotherObj,pTr所引用的anotherObj的空间,在括号结束的时候,anotherObj的生命周期结束,空间就被释放了。而pTr还调用这个被释放的内存,所以引发了野指针崩溃。

解决办法就是在 (#) 使用__bridge_retain ,这样即使是anotherObj的生命周期结束了,由于被pTr持有,retain count不为0,空间会继续保留,这样就不会导致pTr是野指针的情形。也就是说,加了__bridge_retain修饰符以后,编译器进行了retain操作。

void *pTr = 0;
{
   id anotherObj = [[ViewController alloc] init];
   pTr = (__bridge_retain void *)anotherObj; (#)
}
NSLog(@"pTr points class = %@", [(__bridge id)pTr class]); (*)


3、为什么需要__bridge_transfer ?

完全转移对象的所有权,可以防止可能的内存泄漏。

这种场景发生在CF向OC对象转化的过程中。由于CF对象不受ARC的管理,当CF转成OC对象的时候,OC对象可以由ARC管理,CF对象如果不进行release操作,就会导致内存泄漏。

而在转化过程中,将CF对象声明为__bridge_transfer,那么编译器会在完成转化后,自动将CF对象release一次。










评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值