4

これは重複した質問かもしれませんが、私は非常に多くのブログやドキュメントを調べましたが、それでも CFArray とは何かわかりません。

パフォーマンスに関しては、どれが最適で、いつ、どのような状況で使用するかです。このトピックに光を投げてください。

4

3 に答える 3

8

ACFArrayは anNSArrayであり、その逆です。

Core Foundation (CF名前の の由来) は、関数とデータ型の Apple の C 指向のコレクションです。Cocoa (はNS、Cocoa の祖先である NextStep から派生したもの) は、Apple の Objective-C フレームワークです。

つまり、データ構造は 2つのフレームワーク間で共有され、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

于 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() (コメント化されています) を使用して文字列を作成することです。しかし、この方法ははるかに遅く、文字列割り当てのパフォーマンスではなく、配列のパフォーマンスを比較することに関心があります。コードの 2 番目の部分では、配列カウントを取得し、別のループをセットアップして、反復ごとにインデックスの値を取得します。文字列に対して実際には何もしません。

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() の必要性がなくなります。このコードのほとんどは一目瞭然なので、詳しくは説明しません。ただし、1 つ注意しなければならないのは、Foundation には Fast Enumeration を使用するオプションがあることです。これにより、後で説明するように、実際にパフォーマンスが向上します。これは、従来の for ループの横にコメント アウトされています。

于 2016-04-22T05:54:56.953 に答える