标签:
2013-12-08 22:52 1978人阅读
转载自: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 框架参考。
引子
- id obj = [[NSObject alloc] init];
- void *p = obj;
- id obj = p;
- [obj release];
- error: implicit conversion of an Objective-C pointer
- to ’void *’ is disallowed with ARC
- void *p = obj;
- ^
-
- error: implicit conversion of a non-Objective-C pointer
- type ’void *’ to ’id’ is disallowed with ARC
- id o = p;
- ^
__bridge
__bridge 关键字来实现id类型与void*类型的相互转换。看下面的例子。
- id obj = [[NSObject alloc] init];
-
- void *p = (__bridge void *)obj;
-
- id o = (__bridge id)p;
除过 __bridge 以外,还有两个 __bridge 相关的类型转换关键字:
__bridge_retained
- __bridge_transfer
__bridge_retained
- id obj = [[NSObject alloc] init];
-
- void *p = (__bridge_retained void *)obj;
- id obj = [[NSObject alloc] init];
-
- void *p = obj;
- [(id)p retain];
- void *p = 0;
-
- {
- id obj = [[NSObject alloc] init];
- p = (__bridge_retained void *)obj;
- }
-
- NSLog(@"class=%@", [(__bridge id)p class]);
__bridge_transfer
如果ARC无效的时候,我们可能需要写下面的代码。
- // p 变量原先持有对象的所有权
- id obj = (id)p;
- [obj retain];
- [(id)p release];
- // p 变量原先持有对象的所有权
- id obj = (__bridge_transfer id)p;
1。
Toll-Free bridged
这两种对象间可以互相转换和操作,不使用ARC的时候,单纯的用C原因的类型转换,不需要消耗CPU的资源,所以叫做 Toll-Free bridged。比如 NSArray和CFArrayRef, NSString和CFStringRef,他们虽然属于不同的 Framework,但是具有相同的对象结构,所以可以用标准C的类型转换。
- NSString *string = [NSString stringWithFormat:...];
- CFStringRef cfString = (CFStringRef)string;
但是在ARC有效的情况下,将出现类似下面的编译错误:
- Cast of Objective-C pointer type ‘NSString *’ to C pointer type ‘CFStringRef’ (aka ‘const struct __CFString *’) requires a bridged cast
- Use __bridge to convert directly (no change in ownership)
- 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管理)在转换时,需要告诉编译器怎样处理对象的所有权。
- NSString *string = [NSString stringWithFormat:...];
- CFStringRef cfString = (__bridge CFStringRef)string;
- NSString *string = [NSString stringWithFormat:...];
- CFStringRef cfString = (__bridge_retained CFStringRef)string;
- ...
- CFRelease(cfString); // 由于Core Foundation的对象不属于ARC的管理范畴,所以需要自己release
实际上,Core Foundation 内部,为了实现Core Foundation对象类型与Objective-C对象类型的相互转换,提供了下面的函数。
- CFTypeRef CFBridgingRetain(id X) {
- return (__bridge_retained CFTypeRef)X;
- }
-
- id CFBridgingRelease(CFTypeRef X) {
- return (__bridge_transfer id)X;
- }
- NSString *string = [NSString stringWithFormat:...];
- CFStringRef cfString = CFBridgingRetain(string);
- ...
- CFRelease(cfString); // 由于Core Foundation不在ARC管理范围内,所以需要主动release。
__bridge_transfer
- CFStringRef cfString = CFStringCreate...();
- NSString *string = (__bridge_transfer NSString *)cfString;
-
- // CFRelease(cfString); 因为已经用 __bridge_transfer 转移了对象的所有权,所以不需要调用 release
- CFStringRef cfString = CFStringCreate...();
- 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