7

バックグラウンド - バッチ unfaulting:
NSFetchRequest はバッチ unfault を可能にします - たとえば、1000 の結果のクエリを使用すると、すべてが fault として返され、一度に X 個のオブジェクトが unfault されます (つまり、インデックス 0-20、次に 21-40 など)。

この動作は、UITableViewDataSource の NSFetchResultsController で使用する場合に優れており、オブジェクトを 1 つずつアンフォールトしないため、UI の高速スクロールが可能になります。

ここで私の問題:オブジェクトのリストに順序付けられた関係を使用しています。たとえば、
Posts としましょう。

Postはモデルの多くのリストに表示される可能性があるため、Post エンティティのすべてのリストにそのインデックスを保存して、結果を並べ替えるためのパラメーターとして使用することはできませ

今のところ、NSFetchRequest がこの順序に従って取得する方法が見つからないため、そのバッチ unfaulting を使用できません。だから私はインデックスとの関係に取り組んでいます.1つずつunfaultingしてしまい、スクロールがでこぼこになります.

NSFetchResultsController が順序関係に従ってフェッチする方法はありますか? または、プライベートではないバッチ unfaulting API はありますか?

4

2 に答える 2

3

現在、私はそのための解決策を持っていますが、きれいなものではありません
.順序付けられた関係で、20のグループでunfaultをバッチ処理したいと考えています.

そのため、インデックスが 20 で除算されるインデックス (インデックス % 20 == 0) に対処するたびに、次の 20 に対して新しい NSFetchRequest を使用し、共通のフィールド名を呼び出してそれらを unfault します。

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
    if (indexPath.row % 20 == 0) {
        NSArray *objectsToUnfault = [[someObject.orderedRelationship array] subarrayWithRange:NSMakeRange(indexPath.row, MIN(20, [someObject.orderedRelationship count] - indexPath.row))];
        // It's important to hold on this array, otherwise objects fault back
        self.lastPrefetch = [self preFetchEntityOfClass:[Post class] faultObjects:objectsToUnfault error:&error];
    }
//... continue and create cell
}


- (NSArray *)preFetchEntityOfClass:(Class)entityClass faultObjects:(NSArray*)objects error:(NSError **)error {
    NSEntityDescription *entityDescription = [NSEntityDescription entityForName:NSStringFromClass(entityClass) inManagedObjectContext:self.managedObjectContext];
    NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF in %@", objects];
    NSFetchRequest *request = [[NSFetchRequest alloc] init];
    [request setEntity:entityDescription];
    [request setPredicate:predicate];
    [request setFetchBatchSize:MIN([objects count], 20)];
    NSArray *results = [self.managedObjectContext executeFetchRequest:request error:error];
    // I assume all my objects has this field "uid"
    NSArray *resultsUid = [results valueForKey:@"uid"]; //Batch unfaulting (results is a BatchFaultArray, private class type)
    if ([resultsUid count] != [results count]) {
        NSLog(@"Error: wrong count of uids"); //We need to use resultsUid, to avoid compiler opt
    }
    return results;
}
于 2013-06-25T08:19:07.140 に答える
1

あなたの質問を正しく理解できたと思います。

答えを見つけました。答えとadonohoのコメントを見てください

NSFetchedResultsController と NSOrderedSet の関係

于 2013-06-20T17:16:06.697 に答える