什么是 CFArray 以及 CFArray 与 NSArray 的区别

问题描述 投票:0回答:3

这可能是一个重复的问题,但我已经浏览了很多博客和文档,但仍然无法弄清楚

CFArray
是什么。

CFArray
NSArray
有什么区别?就性能而言,我什么时候应该使用其中一种而不是另一种?

objective-c nsarray
3个回答
9
投票

A

CFArray
NSArray
,反之亦然。

Core Foundation(名称中的

CF
的来源)是 Apple 面向 C 的函数和数据类型的集合。 Cocoa(
NS
来自 NextStep,Cocoa 的祖先)是 Apple 的 Objective-C 框架。

这两个框架中的某些类型是免费桥接 - 这意味着数据结构在两个框架之间共享,Core Foundation 使用 C 风格的函数调用对其进行操作,Cocoa 使用 Objective-C 风格的方法对其进行操作来电。

有时,一个框架可能提供另一个框架不提供的操作,但一般来说,在考虑免费桥接类型时,您会使用 Objective-C 中的 Cocoa 和 C 中的 Core Foundation。

Cocoa 对象由 ARC 自动管理,这是一个很大的优点。在 Core Foundation 中,您使用手动内存管理。 Objective-C 有许多“桥”转换,当您在 ARC 和手动 Core Foundation 调用之间转移内存管理责任时,它们会通知编译器。

考虑到它们是相同的数据结构,任何性能差异都归结为额外的调用级开销(如果 Cocoa 方法只调用 Core Foundation 方法)等。一般来说,您不应该担心这一点,除非您“已发现性能问题。

HTH


5
投票
CFMutableArrayRef array = CFArrayCreateMutable(kCFAllocatorDefault, arraySize, &kCFTypeArrayCallBacks);
for (int i=0;i<arraySize;i++) {
    CFStringRef string = CFBridgingRetain(@"This is an awesome string"); // CFStringCreateWithCString(kCFAllocatorDefault, "This is an awesome string", kCFStringEncodingUTF8);
    CFArrayAppendValue(array, string);
    CFRelease(string);
}

CFIndex count = CFArrayGetCount(array);
for (int i=0;i<count;i++) {
    CFStringRef string = CFArrayGetValueAtIndex(array, i);
}
CFRelease(array);

让我们回顾一下 CFArray 代码。在CoreFoundation版本中,我们首先通过CFArrayCreateMutable()函数调用创建一个可变的CFArray(CFMutableArray),提供分配器、数组大小和回调函数。然后,我们设置一个非常传统的 for 循环,以 arraySize 指示的次数迭代数组(该数字将在我们的测试中改变)。然后创建一个字符串并将其附加到数组中并释放。您可能会注意到,我们实际上创建了 Objective-C 字符串文字,并通过 CFBridgingRetain() 将所有权转移到 CoreFoundation。这意味着 ARC 将不再负责为我们释放字符串,我们必须使用 CFRelease() 显式地执行此操作。另一种方法是通过 CoreFoundation 调用 CFStringCreateWithCString() (已注释掉)来创建字符串,但此方法要慢得多,而且我们感兴趣的是比较数组性能,而不是字符串分配性能。代码的第二部分将获取数组计数,设置另一个循环并在每次迭代时获取索引处的值。我们实际上并没有对字符串做任何事情。

NSMutableArray *container = [[NSMutableArray alloc] initWithCapacity:arraySize];
for (int i=0;i<arraySize;i++) {
    NSString *string = @"This is an awesome string";
    [container addObject:string];
}

NSUInteger count = [container count];
for (int i=0;i<count;i++) { // (NSString *string in container) {
    NSString *string = container[i];
}

Objective-C Foundation 的对应项本质上非常相似,但消除了对 CFRelease() 的需要,因为我们在 ARC 下。大部分代码都是不言自明的,因此我们不会详细介绍它。然而,需要指出的一件事是,使用 Foundation,您可以选择使用快速枚举,这实际上会给您带来一些性能提升,正如我们稍后将看到的。这在传统的 for 循环旁边被注释掉了。


2
投票

需要注意的是,虽然其他答案在常见情况下是正确的,但有可能创建与 Objective C 完全不兼容的

CFArray
变体。当创建
CFArray
时,会提供 回调函数。如果提供了标准
kCFTypeArrayCallBacks
,则数组确实兼容并且免费桥接到 Objective C。但是,可以提供自定义回调函数,例如,包含值类型作为数组值(而
NSArray
要求所有值均为
CFType
/
objc_object
)。

了解这种差异很重要,因为在某些罕见的情况下,Apple 框架会返回

CFArray
对象,而这些对象不得桥接至
NSArray
,尤其是在使用 ARC 时。

© www.soinside.com 2019 - 2024. All rights reserved.