Objective-C 和 Core Foundation 对象相互转换的内存管理

iOS允许Objective-C 和 Core Foundation 对象之间可以轻松的转换,拿 NSString 和 CFStringRef 来说,直接转换豪无压力:

CFStringRef aCFString = (CFStringRef)aNSString;

NSString *aNSString = (NSString *)aCFString;

针对内存管理问题,ARC 可以帮忙管理 Objective-C 对象, 但是不支持 Core Foundation 对象的管理,所以转换后要注意一个问题:谁来释放使用后的对象。 本文重点总结一下类型转换后的内存管理。

一、非ARC的内存管理

倘若不使用ARC,手动管理内存,思路比较清晰,使用完,release转换后的对象即可。

//NSString 转 CFStringRef   
CFStringRef aCFString = (CFStringRef) [[NSString alloc] initWithFormat:@"%@", string];  
//...   
CFRelease(aCFString);  
  
  
//CFStringRef 转 NSString   
CFStringRef aCFString = CFStringCreateWithCString(kCFAllocatorDefault,  
                                                  bytes,  
                                                  NSUTF8StringEncoding);  
NSString *aNSString = (NSString *)aCFString;  
//...   
[aNSString release];

二、ARC下的内存管理

ARC的诞生大大简化了我们针对内存管理的开发工作,但是只支持管理 Objective-C 对象, 不支持 Core Foundation 对象。Core Foundation 对象必须使用CFRetain和CFRelease来进行内存管理。那么当使用Objective-C 和 Core Foundation 对象相互转换的时候,必须让编译器知道,到底由谁来负责释放对象,是否交给ARC处理。只有正确的处理,才能避免内存泄漏和double free导致程序崩溃。

根据不同需求,有3种转换方式

  1. __bridge                        (不改变对象所有权)
  2. __bridge_retained 或者 CFBridgingRetain()               (解除 ARC 所有权)
  3. __bridge_transfer 或者 CFBridgingRelease()             (给予 ARC 所有权)

1. __bridge_retained 或者 CFBridgingRetain()

__bridge_retained 或者 CFBridgingRetain()  将Objective-C对象转换为Core Foundation对象,把对象所有权桥接给Core Foundation对象,同时剥夺ARC的管理权,后续需要开发者使用CFRelease或者相关方法手动来释放对象。

来看个例子:

- (void)viewDidLoad  
{  
    [super viewDidLoad];  
      
    NSString *aNSString = [[NSString alloc]initWithFormat:@"test"];  
    CFStringRef aCFString = (__bridge_retained CFStringRef) aNSString;  
      
    //正确的做法应该执行CFRelease   
    //CFRelease(aCFString);    
}

程序没有执行CFRelease,造成内存泄漏:

CFBridgingRetain()  是 __bridge_retained 的宏方法,下面两行代码等价:

CFStringRef aCFString = (__bridge_retained CFStringRef) aNSString;  
CFStringRef aCFString = (CFStringRef) CFBridgingRetain(aNSString);

2. __bridge_transfer 或者 CFBridgingRelease()

__bridge_transfer 或者 CFBridgingRelease()  将非Objective-C对象转换为Objective-C对象,同时将对象的管理权交给ARC,开发者无需手动管理内存。

接着上面那个内存泄漏的例子,再转成OC对象交给ARC来管理内存,无需手动管理,也不会出现内存泄漏:

- (void)viewDidLoad  
{  
    [super viewDidLoad];  
      
    NSString *aNSString = [[NSString alloc]initWithFormat:@"test"];  
    CFStringRef aCFString = (__bridge_retained CFStringRef) aNSString;  
    aNSString = (__bridge_transfer NSString *)aCFString;  
}

CFBridgingRelease() 是__bridge_transfer的宏方法,下面两行代码等价:

aNSString = (__bridge_transfer NSString *)aCFString;

aNSString = (NSString *)CFBridgingRelease(aCFString);

3. __bridge

__bridge 只做类型转换,不改变对象所有权,是我们最常用的转换符。

从OC转CF,ARC管理内存:

- (void)viewDidLoad  
{  
    [super viewDidLoad];  
      
    NSString *aNSString = [[NSString alloc]initWithFormat:@"test"];  
    CFStringRef aCFString = (__bridge CFStringRef)aNSString;  
      
    (void)aCFString;  
}

从CF转OC,需要开发者手动释放,不归ARC管:

- (void)viewDidLoad  
{  
    [super viewDidLoad];  
      
    CFStringRef aCFString = CFStringCreateWithCString(NULL, "test", kCFStringEncodingASCII);  
    NSString *aNSString = (__bridge NSString *)aCFString;  
      
    (void)aNSString;  
      
    CFRelease(aCFString);  
}

Objective-C:Objective-C 和 Core Foundation 对象相互转换的内存管理的更多相关文章

  1. Objective-C 和 Core Foundation 对象相互转换的内存管理总结

    本文转载至 http://blog.csdn.net/allison162004/article/details/38756649 OS允许Objective-C 和 Core Foundation ...

  2. Objective-C 和 Core Foundation 对象相互转换

    iOS同意Objective-C 和 Core Foundation 对象之间能够轻松的转换: CFStringRef aCFString = (CFStringRef)aNSString; NSSt ...

  3. IOS开发之—— Core Foundation对象与OC对象相对转换的问题

    对ARC盲目依赖的同学: 1过度使用block后,无法解决循环引用问题 2遇到底层Core Foundation对象,需要自己手工管理它们的引用计数时,显得一筹莫展 first:对于底层Core Fo ...

  4. Objective-C对象与Core Foundation对象

    Core Foundation 对象主要使用在用C语言编写的Core Foundation 框架中,并引用计数的对象.与Objective-C对象差别非常少.不管哪种框架生成的对象,一旦生成,便可在两 ...

  5. .net core中的高效动态内存管理方案

    .net core在新增的System.Buffers中引入了一大堆高效内存管理的类,如span和memory.内存池.本文今天这里介绍一个高效动态内存访问方案. ReadOnlySequenceSe ...

  6. OC对象与Core Foundation对象的转换

    OC对象使用了ARC,自己主动释放内存,可是CF中的对象没有ARC,必需要手动进行引用计数和内存释放. 两者对象之间的互相转换有三种形式: 1.__bridge: 直接转换,部改变对象的持有状况: i ...

  7. Core Foundation框架

    转载自:http://blog.csdn.net/weiwangchao_/article/details/7744972 Core Foundation框架 (CoreFoundation.fram ...

  8. Foundation与Core Foundation内存管理基本原则简述

    内存管理是一个十分重要的事情,稍有不慎就会发生内存泄漏或者是野指针的错误.内存泄漏一般表示没有任何指针指向的内存区域,由于这块内存在对象图中无法查找到,所以有可能永远都无法回收,如果内存泄漏的空间比较 ...

  9. Core Foundation 框架

    Core Foundation框架 (CoreFoundation.framework) 是一组C语言接口,它们为iOS应用程序提供基本数据管理和服务功能.下面列举该框架支持进行管理的数据以及可提供的 ...

随机推荐

  1. 2017年上海金马五校程序设计竞赛:Problem C : Count the Number (模拟)

    Description Given n numbers, your task is to insert '+' or '-' in front of each number to construct ...

  2. [bzoj1031][JSOI2007]字符加密Cipher——后缀数组

    Brief Description 给定一个长度为n的字符串,你需要对其进行加密. 把字符串围成一个环 显然从任意一个位置开始都可以有一个长度为n的串 把产生的n个串按字典序排序,把这n个串的最后一个 ...

  3. 无线路由器中WMM/Short GI/AP隔离各是什么功能, 开启时PC无法ping通手机.

      无线路由器的WMM功能和开启ap隔离,以及开启ShortGI有什么用 无线路由器中有开启WMM.开启Short GI和开启AP隔离分别代表什么呢?这是我在我的TP-LINK无线路由器TL-WR84 ...

  4. shell命令行混合进制计算器smartbc

    需要简单的计算的时候,不想用GUI的计算器,能在shell下直接计算就最好了 查了下,有个东西叫 bc,  具体的使用就不赘述了,可以运行bc,然后进去计算,也可以echo传递过去,大概是像这样 ec ...

  5. Kuangbin 带你飞 最小生成树题解

    整套题都没什么难度. POJ 1251 Jungle Roads #include <map> #include <set> #include <list> #in ...

  6. 浅谈redux 中间件的原理

    在使用redux管理异步数据流的时候,我们会使用中间件,以redux-thunk中间件为例,我们做一下分析: 首先是构建store,我们需要以下代码进行揉入中间件的类似creatStore函数的构造: ...

  7. GIt 和 Github

    原创 by zoe.zhang        GitHub中采用的比较多得是markdown的语法,博客园里对markdown的支持感觉不是特别友好,但是为了应景,还是用了markdown来写这一篇文 ...

  8. java servlet输出数据

    httpServletResponse.setContentType("text/html;charset=UTF-8"); httpServletResponse.getWrit ...

  9. css左右箭头

    .record-left{ content: ""; width: 0; height: 0; float: left; border-top: 10px solid transp ...

  10. webpack-dev-server坑

    转载人家滴 https://segmentfault.com/q/1010000007561947/a-1020000007596130 需要webpack开发服务(webpack-dev-serve ...