`
xidajiancun
  • 浏览: 457384 次
文章分类
社区版块
存档分类
最新评论

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

 
阅读更多

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种转换方式
  • __bridge (不改变对象所有权)
  • __bridge_retained或者CFBridgingRetain() (解除ARC 所有权)

  • __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;
    
    (void)aCFString;
    
    //正确的做法应该执行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 2.0 运行时系统编程指南

    Objective-C语言将决定尽可能的从编译和链接时推迟到运行时。只要有可能,Objective-C总是使用动态的方式来解决问题。这意味着Objective-C语言不仅需要一个编译器,同时也需要一个运行时系统来执行编译好的代码。这儿...

    Objective-C高级编程 iOS与OS X多线程和内存管理_Objective-C_ios_

    Objective-C高级编程 iOS与OS X多线程和内存管理.pdf

    Objective-C Runtime测试代码

    Objective-C语言的许多决策可以在编译和运行时执行。只要有可能,它是动态的。这意味着Objective-C语言不仅需要一个编译器,还需要一个运行时系统来执行编译的代码。Runtime系统是一种用于Objective-C语言的操作系统...

    Objective-C程序设计

    第7章到第10章讲述objective-c的基础框架,以及文件操作、内存管理、数据保存等内容。第11章讲述了应用工具框架。第12、13章分别讲述了如何开发iphone/ipad应用程序。第14章讲述了objective-c++和访问mysql数据库的...

    Objective-C语言教程

    通过学习Objective-C的基本语法、类和对象、控制流程和方法等内容,你将能够编写简单的Objective-C程序并逐渐掌握更复杂的概念。继续学习和实践,你将能够开发各种类型的应用程序,并为用户提供出色的体验。祝你在...

    Objective-C程序设计(第4版)(全球最畅销Objective-C编程书籍)

     《Objective-C 程序设计(第4版)》已经为iOS 5和Xcode4.2中的重大变更做了全面更新,最大的改动是引入了自动引用计数(ARC),并详细说明了如何在Objective-C编程过程中使用ARC提升和简化内存管理。

    Objective-C高级编程 iOS与OS X多线程和内存管理.

    Objective-C高级编程 iOS与OS X多线程和内存管理.

    Objective- C的模拟对象基于Objective- C的模拟对象.zip

    Objective- C的模拟对象Objective- C的模拟对象Objective- C的模拟对象Objective- C的模拟对象Objective- C的模拟对象Objective- C的模拟对象Objective- C的模拟对象Objective- C的模拟对象

    Objective-C基础教程+随书源代码

     本书全面而系统地讲述Objective-C语言的基础知识和面向对象编程的重要概念,结合实例介绍了Cocoa工具包的优秀特性和其中的框架,以及继承、复合、源文件组织、内存管理、对象初始化和类别创建等众多重要的面向对象...

    用Objective-C语言实现了各种设计模式,收集各种例子,方便大家学习和普及设计模式 .zip

    用Objective-C语言实现了各种设计模式,收集各种例子,方便大家学习和普及设计模式。.zip用Objective-C语言实现了各种设计模式,收集各种例子,方便大家学习和普及设计模式。.zip用Objective-C语言实现了各种设计...

    C语言主要知识点巩固(学习Objective-C 的前提)

    C语言主要知识点巩固(学习Objective-C 的前提),PPT格式。

    Object-C语言教程-提供了 Objective-C 的基本语法和一些示例,希望能够帮助你快速入门 Objective-C

    Objective-C 是一种通用、面向对象的编程语言,广泛应用于 macOS 和 iOS 等苹果平台的开发中。它是 C 语言的超集,结合了 Smalltalk 式的消息传递机制和 C++ 的特性。Objective-C 是苹果公司采用的主要编程语言之一...

    Objective-C基础教程 中文 PDF 清晰版 [31M]

    本书结合理论知识与示例程序,全面而系统地讲述Objective-C编程的相关内容,包括Objective-C在C的基础上引入的特性和Cocoa工具包的功能及其中的框架,以及继承、复合、源文件组织等众多重要的面向对象编程技术。...

    Objective-C 2.0程序设计

    部分详细阐述了Foundation框架,涵盖数字、字符串、集合、文件操作、内存管理、对象复制和归 档等重要内容;第三部分简要介绍了Cocoa和iPhone SDK;第四部分是附录,主要列出了Objective- C的快速参考。  本书结构...

    《Objective-C2.0程序设计(原书第2版)》_中文完整版

    第二部分详细阐述了Foundation框架,涵盖数字、字符串、集合、文件操作、内存管理、对象复制和归档等重要内容;第三部分简要介绍了Cocoa和iPhone SDK;第四部分是附录,主要列出了Objective-C的快速参考。 ...

    清晰版:《精通 Objective-C》

    Objective-C 基础教程,从入门到精通 Objective-C 基础教程,从入门到精通,是你学习 Objective-C 的经典之作。

    《Objective-C 2.0程序设计(原书第2版)》[PDF]

    第二部分详细阐述了foundation框架,涵盖数字、字符串、集合、文件操作、内存管理、对象复制和归档等重要内容;第三部分简要介绍了cocoa和iphone sdk;第四部分是附录,主要列出了objective-c的快速参考。. 本书结构...

    Objective-C基础教程(第2版).pdf

    本书结合理论知识与示例程序,全面而系统地讲述Objective-C编程的相关内容,包括Objective-C在C的基础上引入的特性和Cocoa工具包的功能及其中的框架,以及继承、复合、源文件组织等众多重要的面向对象编程技术。...

    windows 下搭建 Objective-C 开发环境

    在windows系统下搭建Objective-C开发环境,由于公司要做iphone开发,个人学习objc(Objective-C)语法,所以在windows7下搭建了一个objc开发环境,现把自己整理的帮助文档拿来与大家分享,希望能对大家有所帮助。...

Global site tag (gtag.js) - Google Analytics