码迷,mamicode.com
首页 > 其他好文 > 详细

Core Foundation 框架

时间:2015-06-23 19:43:09      阅读:109      评论:0      收藏:0      [点我收藏+]

标签:

Core Foundation 框架

目录(?)[+]

转载自:http://blog.csdn.net/weiwangchao_/article/details/7744972

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

  • 群体数据类型 (数组、集合等)

  • 程序包

  • 字符串管理

  • 日期和时间管理

  • 原始数据块管理

  • 偏好管理

  • URL及数据流操作

  • 线程和RunLoop

  • 端口和soket通讯

Core Foundation框架和Foundation框架紧密相关,它们为相同功能提供接口,但Foundation框架提供Objective-C接口。如 果您将Foundation对象和Core Foundation类型掺杂使用,则可利用两个框架之间的 “toll-free bridging”。所谓的Toll-free bridging是说您可以在某个框架的方法或函数同时使用Core Foundatio和Foundation 框架中的某些类型。很多数据类型支持这一特性,其中包括群体和字符串数据类型。每个框架的类和类型描述都会对某个对象是否为 toll-free bridged,应和什么对象桥接进行说明。

如需进一步信息,请阅读Core Foundation 框架参考

 

引子

 

  1. id obj = [[NSObject alloc] init];
  2. void *p = obj;

 

  1. id obj = p;
  2. [obj release];

 

  1. error: implicit conversion of an Objective-C pointer
  2. to void *’ is disallowed with ARC
  3. void *p = obj;
  4. ^
  5.  
  6. error: implicit conversion of a non-Objective-C pointer
  7. type void *’ to id is disallowed with ARC
  8. id o = p;
  9. ^

 

__bridge

__bridge 关键字来实现id类型与void*类型的相互转换。看下面的例子。

  1. id obj = [[NSObject alloc] init];
  2.  
  3. void *p = (__bridge void *)obj;
  4.  
  5. id o = (__bridge id)p;

除过 __bridge 以外,还有两个 __bridge 相关的类型转换关键字:

    __bridge_retained
  • __bridge_transfer

__bridge_retained

 

  1. id obj = [[NSObject alloc] init];
  2.  
  3. void *p = (__bridge_retained void *)obj;

 

  1. id obj = [[NSObject alloc] init];
  2.  
  3. void *p = obj;
  4. [(id)p retain];

 

  1. void *p = 0;
  2.  
  3. {
  4. id obj = [[NSObject alloc] init];
  5. p = (__bridge_retained void *)obj;
  6. }
  7.  
  8. NSLog(@"class=%@", [(__bridge id)p class]);

__bridge_transfer

如果ARC无效的时候,我们可能需要写下面的代码。

  1. // p 变量原先持有对象的所有权
  2. id obj = (id)p;
  3. [obj retain];
  4. [(id)p release];

 

  1. // p 变量原先持有对象的所有权
  2. id obj = (__bridge_transfer id)p;

1。

Toll-Free bridged

这两种对象间可以互相转换和操作,不使用ARC的时候,单纯的用C原因的类型转换,不需要消耗CPU的资源,所以叫做 Toll-Free bridged。比如 NSArray和CFArrayRef, NSString和CFStringRef,他们虽然属于不同的 Framework,但是具有相同的对象结构,所以可以用标准C的类型转换。

 

  1. NSString *string = [NSString stringWithFormat:...];
  2. CFStringRef cfString = (CFStringRef)string;

但是在ARC有效的情况下,将出现类似下面的编译错误:

  1. Cast of Objective-C pointer type NSString *’ to C pointer type CFStringRef (aka const struct __CFString *’) requires a bridged cast
  2. Use __bridge to convert directly (no change in ownership)
  3. Use __bridge_retained to make an ARC object available as a +1 CFStringRef (aka const struct __CFString *’)

正因为Objective-C是ARC管理的对象,而Core Foundation不是ARC管理的对象,所以才要特意这样转换,这与id类型向void*转换是一个概念。也就是说,当这两种类型(有ARC管理,没 有ARC管理)在转换时,需要告诉编译器怎样处理对象的所有权。

 

  1. NSString *string = [NSString stringWithFormat:...];
  2. CFStringRef cfString = (__bridge CFStringRef)string;

 

  1. NSString *string = [NSString stringWithFormat:...];
  2. CFStringRef cfString = (__bridge_retained CFStringRef)string;
  3. ...
  4. CFRelease(cfString); // 由于Core Foundation的对象不属于ARC的管理范畴,所以需要自己release

实际上,Core Foundation 内部,为了实现Core Foundation对象类型与Objective-C对象类型的相互转换,提供了下面的函数。

  1. CFTypeRef CFBridgingRetain(id X) {
  2. return (__bridge_retained CFTypeRef)X;
  3. }
  4.  
  5. id CFBridgingRelease(CFTypeRef X) {
  6. return (__bridge_transfer id)X;
  7. }

 

  1. NSString *string = [NSString stringWithFormat:...];
  2. CFStringRef cfString = CFBridgingRetain(string);
  3. ...
  4. CFRelease(cfString); // 由于Core Foundation不在ARC管理范围内,所以需要主动release。

__bridge_transfer

 

  1. CFStringRef cfString = CFStringCreate...();
  2. NSString *string = (__bridge_transfer NSString *)cfString;
  3.  
  4. // CFRelease(cfString); 因为已经用 __bridge_transfer 转移了对象的所有权,所以不需要调用 release

 

  1. CFStringRef cfString = CFStringCreate...();
  2. NSString *string = CFBridgingRelease(cfString);

总结

 

  • 明确被转换类型是否是 ARC 管理的对象
    • Core Foundation 对象类型不在 ARC 管理范畴内
    • Cocoa Framework::Foundation 对象类型(即一般使用到的Objectie-C对象类型)在 ARC 的管理范畴内
  • 如果不在 ARC 管理范畴内的对象,那么要清楚 release 的责任应该是谁
  • 各种对象的生命周期是怎样的

1. 声明 id obj 的时候,其实是缺省的申明了一个 __strong 修饰的变量,所以编译器自动地加入了 retain 的处理,所以说 __bridge_transfer 关键字只为我们做了 release 处理。

 

Core Foundation 框架

标签:

原文地址:http://www.cnblogs.com/szwiOS/p/4595809.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!