什么是CFArray和CFArray与NSArray之间的区别

时间:2016-04-22 05:40:05

标签: objective-c nsarray cfarraybsearchvalues

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

性能明智哪一个最好,何时使用以及哪种情况。 请注意这个主题。

3 个答案:

答案 0 :(得分:6)

CFArrayNSArray,反之亦然。

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

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

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

可可对象由ARC自动管理,这是一个很大的优势。在Core Foundation中,您使用手动内存管理。 Objective-C有一些"bridge" casts,当您在ARC和手动Core Foundation调用之间转移内存管理职责时,它会通知编译器。

鉴于它们是相同的数据结构,任何性能差异都归结为如果Cocoa方法只调用Core Foundation一个额外的调用级开销,等等。一般情况下你不应该关注这一点,除非您已发现性能问题。

HTH

答案 1 :(得分:4)

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),提供分配器,数组大小和回调函数。然后我们设置一个非常传统的循环,在数组上迭代arraySize指示的时间(这个数字将在我们的测试中改变)。然后创建一个字符串并将其附加到数组并释放。您可能会注意到我们实际创建了Objective-C字符串文字,并通过CFBridgingRetain()将所有权转移到CoreFoundation。这意味着ARC将不再为我们释放字符串,我们必须使用CFRelease()明确地这样做。另一种方法是使用创建一个带有对CFStringCreateWithCString()的CoreFoundation调用的字符串(已注释掉),但是这个方法要慢得多,我们有兴趣比较数组性能,而不是字符串分配性能。代码的第二部分将获得数组计数,设置另一个循环并在每次迭代时获取索引处的值。我们实际上并没有对字符串做任何事情。

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循环旁边被注释掉了。

答案 2 :(得分:0)

请务必注意,虽然其他答案在通常情况下都是正确的,但可以创建与目标C完全不兼容的CFArray变体。创建CFArray时,{提供了{3}}。如果提供了标准callback functions,则该数组确实是兼容的,并且免费桥接到了ObjectiveC。但是,可以提供自定义的回调函数,例如,可以将值类型包括为数组值(而NSArray要求所有值均为CFType / objc_object)。

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