C指针和OC对象之间如何转换

  介绍

这篇文章将为大家详细讲解有关C指针和OC对象之间如何转换,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

<强>核心基础框架

核心基础框架(CoreFoundation.framework)是一组C语言接口,简称CF。

它们为iOS应用程序提供基本数据管理和服务功能。

如核心图形核心文本,并且我们可能需要将CF对象和OC对象进行相互转化,弧下,编译器不会自动管理CF对象的内存,我们需要手动管理。

创建一个CF对象使用后,需要使用CFRelease将其手动释放,换句话说,核心基础对象类型不在电弧管理范畴内。

如何将CF和OC对象有效的结合起来,在弧环境下,提供了桥接的技术,即电弧下OC对象和核心基础对象之间的桥梁。

<>强电弧桥接

弧下C指针与OC指针(对象)之间转换,一般会用到下面的方法。

 __bridge_retained  & lt; # CF 类型#祝辞)& lt; #表达式#比;
  __bridge_transfer  & lt; # Objective-C 类型#祝辞)& lt; #表达式#比;
  __bridge  & lt; #类型#祝辞)& lt; #表达式#在

也就是所谓的桥接,它是object - C在弧环境下开发出来的一种用作转换C指针跟OC(类)指针的一种转换技术,所以是电弧下的称谓,在MRC下没有桥接。

针对内存管理问题,弧可以管理objective - c对象,但不支持核心基础对象的管理,所以转换后要注意一个问题:谁来释放使用后的对象。

结合弧和内存管理、下面分别介绍一下。

核心基础对象必须使用CFRetain和CFRelease来进行内存管理。

当使用objective - c和核心基础对象相互转换的时候,必须让编译器知道,到底由谁来负责释放对象,是否交给弧处理,只有正确的处理,才能避免内存泄漏和双免费导致程序崩溃。

<>强__bridge_retained & lt; # CF型#祝辞)& lt; #表达式#在

__bridge_retained等同于<代码> CFBridgingRetain()

将objective - c对象转换为核心基础对象,把对象所有权桥接给核心基础对象,同时剥夺弧的管理权,后续需要开发者使用CFRelease或者相关方法手动来释放CF对象。

示例:

void  * cPointer;   NSObject  * objc =, [[NSObject  alloc], init);//将,OC 对象转换为,C 指针   cPointer =, (__bridge_retained  void *) objc;//use  cPointer …//需要释放资源   CFRelease (cPointer);

在弧下,CFBridgingRetain实现如下:

NS_INLINE  CF_RETURNS_RETAINED  CFTypeRef  _Nullable  CFBridgingRetain (id  _Nullable  X), {   ,return  (__bridge_retained  CFTypeRef) X;   }

关于CFTypeRef,如下:

typedef  const  CF_BRIDGED_TYPE (id), void  *, CFTypeRef;

所以CFBridgingRetain返回值是const void *类型的。

上面的示例可以改写为:

const  void  * cPointer;   const  NSObject  * objc =, [[NSObject  alloc], init);   时间=cPointer  CFBridgingRetain (objc);   ,//use  cPointer …   ,   CFRelease (cPointer);

<强> __bridge_transfer & lt; # objective - c型#祝辞)& lt; #表达式#在

__bridge_transfer等同于<代码> CFBridgingRelease()

将非OC对象转换为OC对象,同时将对象的管理权交给弧,开发者无需手动管理内存。

示例:

CFUUIDRef  uuid =, CFUUIDCreate (kCFAllocatorDefault);   CFStringRef  strUUID =, CFUUIDCreateString (kCFAllocatorDefault, uuid);   NSString  * str =, (__bridge_transfer  NSString  *) strUUID;//无需释放strUUID//CFRelease (strUUID);   CFRelease (uuid);

CFBridgingRelease实现如下:

NS_INLINE  id  _Nullable  CFBridgingRelease (CFTypeRef  CF_CONSUMED  _Nullable  X), {   ,return  (__bridge_transfer  id) X;   }

上面的示例可以改写为:

CFUUIDRef  uuid =, CFUUIDCreate (kCFAllocatorDefault);   CFStringRef  strUUID =, CFUUIDCreateString (kCFAllocatorDefault, uuid);   NSString  * str =, CFBridgingRelease (strUUID);   ,//无需释放strUUID//CFRelease (strUUID);   ,   CFRelease (uuid);

<强> __bridge

__bridge不改变对象所有权,需要我们自己来管理内存,它也是我们经常使用的方法,从某种程度上来说,它是上面两个方法的简化版本。

C指针和OC对象之间如何转换