8

現在、NSFetchedResultsControllerを使用してコアデータからプロジェクトのUITableViewにデータを取り込みしようとしています。私はこのタブを入力すると、私はすべてのプログラムの上に記録され、NSFetchedResultsControllerがないことを発見したNSFetchedResultsControllerカスタムソートが呼び出されない

if (fetchedResultsController != nil) { 
     return fetchedResultsController; 
    } 

    /* 
    Set up the fetched results controller. 
    */ 
    // Create the fetch request for the entity. 
    NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
    // Edit the entity name as appropriate. 
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Object" inManagedObjectContext:self.managedObjectContext]; 
    [fetchRequest setEntity:entity]; 

    // Set the batch size to a suitable number. 
    [fetchRequest setFetchBatchSize:20]; 
    NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"objectName" ascending:YES comparator:^(id s1, id s2) { 
      NSLog(@"Comparator"); 
     //custom compare here with print statement 
    }]; 
    NSLog(@"Sort Descriptor Set"); 
    NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor, nil]; 
    NSEntityDescription *entity = [NSEntityDescription entityForName:@"Object" inManagedObjectContext:self.managedObjectContext]; 
    [fetchRequest setEntity:entity]; 
    [fetchRequest setSortDescriptors:sortDescriptors]; 

    NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"firstLetterOfObject" cacheName:@"Objects"]; 
    [aFetchedResultsController release]; 
    [fetchRequest release]; 
    [sortDescriptor release]; 
    [sortDescriptors release]; 
    if (![fetchedResultsController performFetch:&error]) { 
     NSLog(@"Unresolved error %@, %@", error, [error userInfo]); 
     abort(); 
    } 

    return fetchedResultsController; 

:私は、コンパレータ(私もセレクタを試してみましたが、同じ問題を抱えているが)とのカスタム検索を使用していますフェッチ時にコンパレータブロックに入ることさえありません。代わりに、デフォルトのソート方法でソートします。

ただし、objectNameを持つオブジェクトを削除して追加すると、コンパレータブロックに入ってテーブルが正しくソートされます。

NSFetchedResultsControllerは、管理対象オブジェクトモデルが変更されるまで、コンパレータを使用してソートしないのはなぜですか?

注:キャッシングをオフにしたり、またはviewDidLoadでフェッチを実行しようとしましたが、フェッチする回数は問題ではありません。何らかの理由で、オブジェクトモデルが変更された後にのみソートを使用します。

答えて

8

物事のカップルがあります。私は考えることができます。まず、これはあなたの問題ではないかもしれませんが、一時プロパティをソートすることはできません。しかし、SQLストアに裏打ちされたモデルでソートすると、コンパイラーはSQL照会に「コンパイル」され、すべてのObjective-C関数が使用できるわけではありません。この場合、フェッチが実行された後にメモリ内でソートする必要があります。

EDIT:詳細はdocを参照してください。具体的には、述語の取得と記述子のセクションを参照してください。

+1

一時的なプロパティではありませんが、他の提案は間違いなく問題の可能性があります。唯一の問題は、セクション名などをテーブルビューに提供するためにfetchedresultscontrollerに依存しているため、毎回メモリ内でソートするのが難しいことです(私は思っています)。あなたはそれについてどうお勧めしますか?そして私の他の質問は、なぜオブジェクトモデルが変更された後にコンパレータブロックが機能するのでしょうか?ありがとうございました! –

+0

実際にはより一般的な問題は、セクションインデックスと共にセクションを私のテーブルビューに実装することです。私は "123"セクション(この作品)に数字で始まるオブジェクトを置いていますが、このセクションをiPodアプリケーションのように下部にしたいと思います。アップルのアプリケーションによると、この数値はsectionIndexの最後のオプションでなければなりません(私はUILocalizedIndexedCollat​​ionを使ってセクションインデックスを生成しています)。しかし、数字が最後に来るようにセクションをフェッチする方法はないようです。カスタムソートよりも信頼性の高い方法を知っていますか? –

+2

ちょっと推測しますが、グラフがすでにメモリに入っているため、オブジェクトモデルが変更された後にコンパレータブロックが機能すると思います。しかし、それはちょうど推測です。手動でソートする方法はNSArrayControllerをサブクラス化することだと思いますので、NSFetchedResultsControllerのメリットを失います。しかし、あなたが言うように、根本的な問題は、数字を一番下に並べ替えることです。私の頭の上から、あなたのオブジェクトにソート順プロパティを作成して使用すると言っていますが、ソート記述子を使って十分なカスタムソートを行っていません。 – Don

0

申し訳ありませんが、あなたは最終的にはあなたのコードスニペットに一部をフェッチ?:

NSError *error; 
BOOL success = [aFetchedResultsController performFetch:&error]; 

すぎ要求を解放することを忘れないでください逃さなかった:

[fetchRequest release]; 
+0

いいえ、スニペットには含めていません。それが明確になるなら、私は全体の方法を含めました。 –

1

私は同じ問題を抱えています。オブジェクトを修正して変更を保存し、元の値に復元してもう一度保存することです。

// try to force an update for correct initial sorting bug 
NSInteger count = [self.fetchedResultsController.sections count]; 
if (count > 0) { 
    id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fetchedResultsController sections] objectAtIndex:0]; 
    count = [sectionInfo numberOfObjects]; 
    if (count > 0) { 
     NSManagedObject *obj = [self.fetchedResultsController objectAtIndexPath:[NSIndexPath indexPathForRow:0 inSection:0]]; 
     NSString *name = [obj valueForKey:@"name"]; 
     [obj setValue:@"X" forKey:@"name"]; 
     // Save the context. 
     [self saveContext]; 
     [obj setValue:name forKey:@"name"]; 
     // Save the context. 
     [self saveContext]; 
    } 
} 
関連する問題