4

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

就性能而言,哪一个是最好的,何时使用以及哪种情况。请在这个话题上有所启发。

4

3 回答 3

8

ACFArray是一个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 方法仅调用核心基础方法的额外调用级开销等。一般而言,除非您已经发现了一个性能问题。

高温高压

于 2016-04-22T05:57:20.813 回答
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 的对应物在本质上非常相似,但由于我们在 ARC 下,因此不需要 CFRelease()。大部分代码都是不言自明的,所以我们不会详细介绍。然而,需要指出的一点是,对于 Foundation,您可以选择使用快速枚举,这实际上会给您带来一些性能提升,我们稍后会看到。这在传统的 for 循环旁边被注释掉了。

于 2016-04-22T05:54:56.953 回答
2

需要注意的是,虽然其他答案在常见情况下是正确的,但可以创建CFArray与 Objective C 完全不兼容的变体。CFArray创建 a 时,会提供回调函数。如果kCFTypeArrayCallBacks提供了标准,则数组确实兼容并且免费桥接到 Objective C。但是,可以提供自定义回调函数,例如,将值类型作为数组值包含在内(而NSArray要求所有值都是CFType/ objc_object)。

了解这种差异很重要,因为在极少数情况下,Apple 框架返回的CFArray对象不能被桥接NSArray,尤其是在使用 ARC 时。

于 2019-06-28T07:10:41.643 回答