2012-04-20 1 views
4

NSDate値を指すキーを使用してNSSortdescriptorを使用してNSFetchRequest結果をソートしようとしています。私の取った結果は、明確な理由がない限り完全にランダムに出てきます。NSSortdescriptorはNSManagedContextからのフェッチ結果で無効です

私が使用しているNSManagedObjectContextは、NSOperationのサブクラスで作成されたネストされた子コンテキストからのセーブで更新されます。私は親(主)コンテキストから必要なすべてのデータを取得できるので、これがすべて正常に完了したことはわかっています。そこからフェッチするだけで日付を並べ替えることはできません!

奇妙なことです。 2つの日付の間にエンティティ(「Tweet」と呼ばれる)を選択するための述語は正常に機能します。ここで

は私の問題を説明するためにいくつかのコードです:NSSortDescriptorは私のフェッチのために働いていない理由

NSSortDescriptor* timeDescriptor = [NSSortDescriptor 
             sortDescriptorWithKey:@"time" 
             ascending:NO 
             selector:@selector(compare:)]; 

NSFetchRequest* request = [NSFetchRequest fetchRequestWithEntityName:@"Tweet"]; 
[request setSortDescriptors:[NSArray arrayWithObjects:timeDescriptor, nil]]; 

NSPredicate* predicate = [NSPredicate predicateWithFormat:@"((time >= %@) AND (time <= %@))",startDate,endDate]; 
[request setPredicate:predicate]; 

NSManagedObjectContext* context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType]; 
[context setParentContext:[[NSApp delegate] managedObjectContext]]; 
[context performBlock:^{ 
    NSError* error = nil; 
    NSArray* results = nil; 

    results = [context executeFetchRequest:request error:&error]; 
    // Results here are not ordered correctly 

    // 2nd try sorting results using fetched array (works!) 
    results = [results sortedArrayUsingDescriptors:[NSArray arrayWithObjects:timeDescriptor, nil]]; 

    // This works too but not needed anymore 
    /*results = [results sortedArrayUsingComparator:^(id obj1, id obj2) { 
     Tweet* tweet1 = (Tweet*)obj1; 
     Tweet* tweet2 = (Tweet*)obj2; 
     //return [tweet1.time compare:tweet2.time]; // ascending 
     return [tweet2.time compare:tweet1.time]; // descending 
    }];*/ 

    if ([results count] > 0) { 
     for (uint i = 0; i < [results count]; i++) { 
      Tweet* tweet = [results objectAtIndex:i]; 
      NSDate* date = Tweet.time; 
      NSLog(@"tweet date: %@", date); 
     } 
    } 
}]; 

誰も教えてもらえますか?

ありがとうございます!

- 更新 -

私がperformBlockメソッドを使用せずに、メインスレッド上のメイン(親)managedObjectContextからフェッチするときNSSortDescriptorが正常に動作しそうです。これは、NSPrivateQueueConcurrencyType managedObjectContextでソートされたフェッチを行うのに役立ちません。 performBlock内にNSFetchRequest、NSSortDescriptor、NSPredicateを作成しても問題は解決されません。比較デフォルトを使用する場合

答えて

-1

:セレクタを、あなたが記述簡素化することができます:

NSSortDescriptor* timeDescriptor = [NSSortDescriptor 
             sortDescriptorWithKey:@"time" 
             ascending:NO]; 

をしかし、それはさておきです。私はキーが入れ子の子のコンテキストから更新しているという事実です。オブジェクトに永続オブジェクトIDがあることを検証します。彼らはまだそれらを受け取っていないかもしれません、そして、それはあなたのフェッチの問題かもしれません。存在する場合は、objectPermanentIDsForObjectsを呼び出してから、ネストされた子コンテキストを保存してください。

4

私も問題に当たった。 データが永続ストアに保存されていない限り、マスターコンテキストのデータが汚れている、つまり変更されている場合、ソートは機能しません。

たとえば、コンテキストがクリーンで変更が保留されていない場合、ソートが機能します。 親コンテキストのエンティティの属性を1つだけ変更すると、プライベートキューの子コンテキストでのソートが機能しません。それは非常に残念です。配列メソッドでソートすることもできますが、NSFetchRequestでソートするほど高速ではありません。特に、データがすでにそのキーによって索引付けされているためです。フェッチ要求でソートする方がはるかに高速でした。

私は、コンテキストに未保存の変更があり、NSFetchRequestはSQLiteデータベース自体に移動するため、変更がまだ存在しない(コンテキストは保存されていない)ので、データベースレベルではまったく並べ替えることができません。

しかし、全体的には非常に混乱し、バグのような匂いがします。

3

私は全く同じ問題を抱えていました。 NSFetchRequestインスタンスのincludesPendingChangesプロパティをNOに設定して問題を解決しました。

関連する問題