Core Foundation 框架

Core Foundation 框架

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 框架参考


自 Xcode4.2 开始导入ARC机制后,为了支持对象间的转型,Apple又增加了许多转型用的关键字。这一讲我们就来了解其用法,以及产生的理由。

引子

我们先来看一下ARC无效的时候,我们写id类型转void*类型的写法:

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

反过来,当把void*对象变回id类型时,只是简单地如下来写,

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

但是上面的代码在ARC有效时,就有了下面的错误:

 
 
  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;

将Objective-C的对象类型用 __bridge 转换为 void* 类型和使用 __unsafe_unretained 关键字修饰的变量是一样的。被代入对象的所有者需要明确对象生命周期的管理,不要出现异常访问的问题。

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

  • __bridge_retained
  • __bridge_transfer

接下来,我们将看看这两个关键字的区别。

__bridge_retained

先来看使用 __bridge_retained 关键字的例子程序:

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

从名字上我们应该能理解其意义:类型被转换时,其对象的所有权也将被变换后变量所持有。如果不是ARC代码,类似下面的实现:

 
 
  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]);

出了大括号的范围后,p 仍然指向一个有效的实体。说明他拥有该对象的所有权,该对象没有因为出其定义范围而被销毁。

__bridge_transfer

相反,当想把本来拥有对象所有权的变量,在类型转换后,让其释放原先所有权的时候,需要使用 __bridge_transfer 关键字。文字有点绕口,我们还是来看一段代码吧。

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

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

那么ARC有效后,我们可以用下面的代码来替换:

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

可以看出来,__bridge_retained 是编译器替我们做了 retain 操作,而 __bridge_transfer 是替我们做了 release1

Toll-Free bridged

在iOS世界,主要有两种对象:Objective-C 对象和 Core Foundation 对象0。Core Foundation 对象主要是有C语言实现的 Core Foundation Framework 的对象,其中也有对象引用计数的概念,只是不是 Cocoa Framework::Foundation Framework 的 retain/release,而是自身的 CFRetain/CFRelease 接口。

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

比如不使用ARC时,我们用下面的代码:

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

同样,Core Foundation类型向Objective-C类型转换时,也是简单地用标准C的类型转换即可。

但是在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 *’)

错误中已经提示了我们需要怎样做:用 __bridge 或者 __bridge_retained 来转型,其差别就是变更对象的所有权。

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

上面的例子,使用 __bridge/__bridge_retained 后的代码如下:

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

只是单纯地执行了类型转换,没有进行所有权的转移,也就是说,当string对象被释放的时候,cfString也不能被使用了。

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

使用 __bridge_retained 可以通过转换目标处(cfString)的 retain 处理,来使所有权转移。即使 string 变量被释放,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. }

所以,可以用 CFBridgingRetain 替代 __bridge_retained 关键字:

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

所有权被转移的同时,被转换变量将失去对象的所有权。当Core Foundation对象类型向Objective-C对象类型转换的时候,会经常用到 __bridge_transfer 关键字。

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

同样,我们可以使用 CFBridgingRelease() 来代替 __bridge_transfer 关键字。

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

总结

由上面的学习我们了解到 ARC 中类型转换的用法,那么我们实际使用中按照怎样的原则或者方法来区分使用呢,下面我总结了几点关键要素。

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

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

  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
### 回答1: Swift项目底层框架可以被称为"万能",是因为它提供了广泛且强大的功能,适用于各种不同类型的应用程序开发。以下是一些Swift项目底层框架的特点和功能: 1. Foundation框架Foundation框架是Swift项目底层框架的核心,提供了许多基本的数据类型、集合和操作,还包括日期和时间处理、文件操作、网络通信等功能。这些功能使得开发者能够更轻松地处理常见的编程任务。 2. UIKit框架:UIKit框架是构建iOS应用程序界面的核心框架,提供了丰富的视图控件、图形绘制、动画效果等。使用UIKit框架,开发者可以快速创建用户友好的界面,并与用户进行交互。 3. Core Data框架Core Data框架是苹果提供的对象图管理和持久化框架,用于管理应用程序的数据模型。它通过对象关系映射(ORM)技术将数据存储到数据库中,并提供了查询、排序、过滤等功能。开发者可以使用Core Data框架轻松地处理数据的创建、读取、更新和删除操作。 4. Core Animation框架Core Animation框架是处理动画效果的底层框架,提供了高性能的动画渲染引擎。通过Core Animation框架,开发者可以实现平滑的动画效果,并对视图进行缩放、旋转、渐变等变换操作。 5. XCTest框架:XCTest框架是苹果提供的用于编写和执行单元测试的框架。开发者可以使用XCTest框架测试代码的正确性和可靠性,确保应用程序的质量和稳定性。 总结起来,Swift项目底层框架提供了丰富的功能和工具,使开发者能够更轻松地构建高性能、用户友好的应用程序。无论是处理数据、绘制界面、实现动画还是进行单元测试,Swift项目底层框架都能满足开发者的需求,并帮助他们快速有效地完成项目开发。 ### 回答2: Swift 是一种适用于开发 iOS、macOS、watchOS 和 tvOS 应用程序的多用途编程语言。它具有基于安全性和可靠性的设计,同时也是一门高效、现代化和易于学习的语言。在 Swift 的底层,有许多重要的框架和库,以帮助开发人员构建强大和功能丰富的应用程序。 其中最重要和常用的一个底层框架是 UIKit。它是一个用户界面框架,为开发 iOS 和 tvOS 应用程序提供了一套丰富的界面组件和工具。UIKit 提供了诸如按钮、标签、图像视图和表视图等各种界面元素,以及用于布局、动画和用户交互的功能。它还提供了许多管理应用程序生命周期、处理用户输入和响应系统事件的类和方法。 另一个重要的底层框架Foundation。它是一个原生的、跨平台的框架,为开发 macOS、iOS、watchOS 和 tvOS 应用程序提供了核心功能和服务。Foundation 包含了一系列核心类,用于处理基本数据类型、日期和时间、文件和目录操作、网络通信等任务。此外,Foundation 还提供了国际化和本地化支持,包括字符串本地化、货币和日期格式化等。 除了 UIKit 和 Foundation,Swift 还支持许多其他底层框架,如 Core Data、Core Animation、Core Graphics 等。这些框架提供了底层的图形处理、动画、数据库和计算功能,以及其他与应用程序开发相关的功能和服务。 总之,Swift 项目的底层框架在许多方面扮演着重要的角色,提供了丰富的工具和功能,帮助开发人员构建出高效、现代化和可靠的应用程序。这些底层框架涵盖了用户界面、数据处理、网络通信、图形处理等方面,为开发人员提供了丰富的选择和灵活性。 ### 回答3: Swift是一种高级、安全和易读的编程语言,可以用于开发iOS、macOS、watchOS和tvOS应用程序。它的底层框架包括以下几个方面: 1. Objective-C 运行时框架:Swift利用Objective-C运行时框架来实现与Objective-C语言的互操作性。这包括使用Objective-C的类、方法和属性等,以便在Swift代码中调用和使用。 2. Foundation框架Foundation是一个核心框架,提供了许多基本类和功能,可以用于开发各种应用程序。它包括字符串处理、集合和数据结构、文件操作、网络通信、日期和时间处理等功能。Foundation框架是Swift项目中常用的框架之一。 3. UIKit框架:UIKit是一个用户界面框架,用于开发iOS应用程序。它提供了一系列视图、控制器、布局和动画等功能,可以创建各种用户界面元素。UIKit框架是Swift项目中创建用户界面的主要框架之一。 4. Core Data框架Core Data是一个持久化框架,用于管理应用程序的对象模型和存储。它提供了高效的数据管理和查询功能,并支持数据模型的版本控制和迁移。Core Data框架可以帮助Swift项目实现数据持久化的需求。 5. AVFoundation框架:AVFoundation是一个多媒体框架,用于处理音频、视频和图像等媒体数据。它提供了音频和视频播放、录制和编辑等功能,支持多种媒体格式。AVFoundation框架可以在Swift项目中实现丰富的多媒体功能。 以上几个底层框架是Swift项目中常用和重要的框架之一。通过利用这些框架,开发人员可以更方便地实现各种功能,提高开发效率,并提供更好的用户体验。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值