CF对象与NS对象

我试图理解为什么存在CF和NS对象,它们似乎做同样的事情,并通过免费桥接互换。 如果CFArray和NSArray做同样的事情,而且我可以自由地在两者之间施加压力,那么他们两个都有什么意义呢? 有什么关于什么时候使用一个的规则? CF对象只是旧框架的遗留对象吗? 任何洞察到这将不胜感激。

按顺序回答您的问题:

  1. 他们两个都有什么意义? 有几个原因。

    如果你想提供一个C API,比如Carbon API,你需要像引用计数对象的数组和字典这样的东西,你需要像Core Foundation这样的库(它提供了CFArray ),当然它需要一个C API。

    如果您想要为Windows上的第三方编写库(例如),则需要提供C API。

    如果你想编写一个低级库,比如与你的操作系统的内核进行交互,而你不需要Objective-C消息的开销,那么你需要一个C API。

    所以这些都是拥有纯粹的C库Core Foundation的很好的理由。

    但是,如果您想在Objective-C中提供更高级的,更令人愉快的API,则需要表示数组,字典,引用计数对象等的Objective-C对象。 所以你需要Foundation,这是一个Objective-C库。

  2. 你应该什么时候使用一个或另一个? 一般来说,你应该尽可能地使用Objective-C类(例如NSArray ),因为Objective-C接口更好用: myArray.count (或者[myArray count] )比CFArrayGetCount(myArray) )更容易读写CFArrayGetCount(myArray) 。 只有在真正需要时才应该使用Core Foundation API:当您在没有Objective-C的平台上,或者需要Core Foundation API提供的function,但是Objective-C对象缺less的function时。 例如,您可以在创buildCFArrayCFDictionary时指定callback,以便存储非引用计数的对象。 NSArrayNSDictionary类不会让你这样做 – 他们总是假设你正在存储引用计数的对象。

  3. CF对象只是遗留的对象? 一点也不。 事实上,Nextstep已经存在多年,只有Objective-C基础库和没有(公共)Core Foundation库。 当苹果公司需要在相同的低级操作系统设施上同时支持Carbon API和Cocoa API时,他们创build(或者公开)Core Foundation来支持这两者。

顺便说一下,一些Core Foundation是开源的。 您可以在这里findMac OS X 10.10.5的开源部分: https ://opensource.apple.com/source/CF/CF-1153.18/。 我发现CFRunLoopCFStream的源代码非常丰富。

核心基础是一个C API的各种常见的数据结构。 这些数据结构中的大多数在Cocoa中都有等价的,但不是全部。 大多数相当的免费桥接,允许它们交替使用,但不是全部。

免费桥接是一个非常聪明的实现技巧。 如果你想了解底层细节,请参阅@Matt Wilding指出的ridiculous_fish文章 。 它是这方面最权威的(对iOS有重要的影响:PTL第19章也解释了它是如何工作的)。 但是对于大多数目的来说并不重要。 正如Matt所说,你通常可以假装NSArrayCFArrayRef是一样的。 这在许多情况下并不是真的,但有时候这是真的,而且大部分时间都很接近。 这与@"stuff"NSString包含的stuff是一样的。 这大部分是真的,但不完全是。

当OS 9移动到OS X时,提供对Objective-C类数据结构的访问非常方便。 由于性能方面的原因,今天许多底层框架都暴露了C API。 你不应该把CF看作“传统”或“内部”。 您应该将其视为低级别,只有在您需要其提供的权力时才应使用它,或者正在处理需要它的底层框架。

CF对象通常比NS对象更灵活。 例如, CFDictionaryRef可以包含非对象键和值,而NSDictionary不能。 (当然,他们免费桥接,所以你可以创build一个非保留的CFDictionaryRef然后把它当作一个NSDictionary 。狡猾的….)

随着Apple发布新的框架,您会注意到他们经常首先公开C API,然后添加Objective-C API。 学习Core Foundation是个好主意,即使你不用每天都这么做。 但是,如果可能的话,你通常应该使用ObjC。

这个问题有一些历史。 核心基金会是这个行动的大脑。 它主要是用C编写的。它是在苹果收购NEXT和它们的API的基础上创build的,对它们有很大的帮助。 NS *类通常只是构build在CF *types之上的Objective C抽象接口。 所以,当你问为什么CFArray和NSArray都存在的时候,答案是他们实际上没有。 NSArrays CFArrays,NSStrings CFStrings等,这就是为什么免费桥接是可能的。

对于更有趣和更详细的阅读,我会把你推荐到这个博客文章 。

CF代表CoreFoundation。 在名字中含有CF的暴露对象只是常规的Core Foundation对象,用C语言编写。所有的对象都可以免费与Cocoa Touch Foundation的朋友在Objective-C的地盘上桥接。 他们通常是不透明的指针。

NS表示NextStep,它是Mac OS X构build的旧操作系统。 NS前缀的对象通常完全用Objective-C或C或者甚至一些C ++编写。

这真的取决于你需要做什么每个对象。 对于使用NSString的纯Objective-C来说,这对我来说当然更容易,那么对于我来说就是将C和Objective-C与CFString混合在一起工作,但是CF对象可以做一些事情,NS对象可以“吨(主要是非常低水平的东西)。 CF对象也比NS对手在Ref,突变和检查方面涉猎更多。

(为了将来的参考,还有几个前缀:CoreGraphics的CG,UIKit的UI,QuickLook的QL,AVFoundation的AV,MediaPlayer的MP,MessageFoundation的MF,GL的GLKit和MK的MapKit)错过任何,我会很乐意编辑)。