4

NSFetchedResultsControllerを使用してTableViewに表示したいプロパティ「date」を持つCoreDataクラス「Meeting」があります。会議は2つの方法で並べ替える必要があります。最初に、月のすべての会議を同じセクションにまとめ、月/セクションのすべての会議を日付で並べ替える必要があります。

    NSComparisonResult (^periodSortBlock)(id, id) = ^(id obj1, id obj2) {                
        NSLog(@"Debug");            

        NSDate *date1 = (NSDate *)obj1;
        NSDate *date2 = (NSDate *)obj2;

        // Pseudocode
        Month *month = [Month monthWithDate:date1];
        NSComparisonResult result = NSOrderedSame;

        if ([Month date:date2 afterDate:month.end])
            result = NSOrderedAscending;
        else if ([Month date:date2 beforeDate:month.start])
            result = NSOrderedDescending;

        return result;
    };        

    NSFetchRequest *fetchRequest = [NSFetchRequest fetchRequestWithEntityName:@"Meeting"];        
    fetchRequest.predicate = [NSPredicate predicateWithFormat:@"SELF IN %@", self.meetings];

    NSSortDescriptor *sectionByMonth = [NSSortDescriptor sortDescriptorWithKey:@"date" ascending:false comparator:periodSortBlock];
    NSSortDescriptor *sortByDate = [NSSortDescriptor sortDescriptorWithKey:@"date" ascending:false];

    fetchRequest.sortDescriptors = [NSArray arrayWithObjects:sectionByMonth, sortByDate, nil];

    frc = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"date" cacheName:nil];
    [frc performFetch:nil];

コードはエラーなしでコンパイルされますが、並べ替えは期待どおりに機能しません。すべての会議には独自のセクションがあります。

私が見る限り、ソートブロックは完全に無視され、呼び出されません。NSLogステートメントは出力を生成せず、ブロック内のブレークポイントは実行を停止しません。

sortDescriptorWithKey:ascending:comparatorの代わりに:sortDescriptorWithKey:ascending:を使用できます。結果はまったく同じです。

ブロックがsortDescriptorWithKey:ascending:comparator:ステートメントで直接宣言されている場合、または変数として(上記のように)宣言されている場合も、違いはありません。

ブロックを(id、id)ではなく(NSDate *、NSDate *)として定義することも違いはありません。

ここで何が問題になっていますか?ブロック内の並べ替えでエラーが発生するかどうかはわかります。しかし、ブロックが呼び出されなかった可能性はありますか?

4

1 に答える 1

6

ポールからのヒントのおかげで、私は問題が何であるかを理解することができました。解決策はAppleドキュメントにあります(「述語のフェッチと記述子の並べ替え」セクションを参照してください)。

NSFetchRequestはSQLを使用してSQLiteDBからオブジェクトをフェッチし、次にSortDiscriptorsを使用してフェッチされたオブジェクトをメモリ内でソートすると思いました。これは真実ではありません。完全な並べ替え作業はSQLiteストアにも渡されているようです。もちろん、ブロックからのObective-CステートメントはSQLクエリに変換できないため、ブロックは無視されます。

于 2012-06-14T10:23:31.087 に答える