知识点和前提
1.开启了ARC
2.OC对象的内存管理由系统处理
3.CF对象的内存管理需要自行处理
4.OC与CF对象转换时需要用到三种关键字__bridge/__bridge_transfer/__bridge_retained
---------------------------------华丽的分割线-------------------------------
1.__bridge
这个关键字可用来类型转换,但并没有改变对象的所有权,也就是在转换的时候不具有release或者retain这样的功能
例子1. OC ===> CF
// __bridge OC ===> FC
void testBridgeForOCToFCObject()
{
CFMutableStringRef cfObj;
{
NSMutableString * ocObj = [[NSMutableString alloc]initWithString:@"this is a string"];
cfObj = (__bridge CFMutableStringRef)(ocObj);
}
NSLog(@"message sent to deallocated log will show %@",[(__bridge id)cfObj description]);
}
上面的效果要需要对Xcode进行一些配置才能看出来
![](https://img.haomeiwen.com/i606979/9443784f7a98cd1e.png)
如果不打开这个配置,是不会报错的,原因在与这个对象虽然被释放了,但是它的内存中的位置,以及数据结构并没有改变,所以调动并没有问题,打开后,运行程序会立即奔溃,并报message sent to deallocated这样的错误
==============================================
例子2. FC ===> OC
// __bridge FC ===> OC
void test_bridge_For_FCTo_OCObject()
{
CFStringRef cfObj = CFStringCreateWithCString(kCFAllocatorDefault, [@"this is a string" UTF8String], kCFStringEncodingUTF8);
NSString * ocObj = (__bridge id)(cfObj);
NSLog(@"this will lead memory leak%@",[ocObj description]);
}
似乎看不出来有没有内存泄露,Xcode工具栏上product->Analyze后会看到
![](https://img.haomeiwen.com/i606979/fe5ab63c5bbaba3e.png)
这也从侧面验证了CF对象不会自动释放
---------------------------------华丽的分割线-------------------------------
2.__bridge_transfer
该关键字的作用只有一个就是将CF对象转换成OC对象,且对CF对象进行了release操作,看例子
// __bridge_transfer FC===>OC
void test_bridge_transfer_OnlyFor_FC_To_OC()
{
CFStringRef cfObj = CFStringCreateWithCString(kCFAllocatorDefault, [@"this is a string" UTF8String], kCFStringEncodingUTF8);
NSString * ocObj = (__bridge_transfer id)(cfObj);
NSLog(@"this will lead memory leak%@",[ocObj description]);
}
Xcode工具栏上product->Analyze后不会看到内存泄露这样的信息了
3.__bridge_retained
该关键字的作用只有一个就是将OC对象转换成CF对象,且对CF对象进行了retain操作,看例子
void test__bridge_retained_OnlyFor_OC_To_FC()
{
CFMutableStringRef cfObj;
{
NSMutableString * ocObj = [[NSMutableString alloc]initWithString:@"this is a string"];
cfObj = (__bridge_retained CFMutableStringRef)(ocObj);
}
NSLog(@"all right %@",[(__bridge id)cfObj description]);
}
运行这段代码,不会产生奔溃这样即使OC对象释放了CF对象仍然可以使用.
总结:
CFBridgingRetain<===> __bridge_retained是等效的
CFBridgingRelease<===>__bridge_transfer是等效的
记住这张图就好了,忘记从哪扣的了
iyQviq.jpg!web.jpeg
网友评论