2012-04-10 7 views
0

エンティティTagsがあります。フェッチを実行して、すべてTagsを取得し、NSFetchedResultsControllerに割り当てたいとします。しかし、取得した結果の最初のオブジェクトがTagtagNameのプロパティが"All"で、残りがアルファベット順にソートされています。現在私はアルファベット順にすべてのタグを返すだけですが、"All"というタグを常に最初に、その後はアルファベット順にしたいと考えています。複数の述語を含む要求を取得しますか?

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
NSEntityDescription *entity = [NSEntityDescription 
            entityForName:@"Tag" inManagedObjectContext:appDelegate.managedObjectContext]; 

[fetchRequest setEntity:entity]; 
NSSortDescriptor *lastDescriptor = 
[[[NSSortDescriptor alloc] initWithKey:@"tagName"ascending:YES selector:@selector(localizedCaseInsensitiveCompare:)] autorelease];  

[fetchRequest setSortDescriptors:[NSArray arrayWithObject:lastDescriptor]]; 
+0

あなたがメソッドlocalizedCaseInsensitiveCompareを投稿することができセレクタは と同じメソッドシグネチャを持っている必要がありますか?新しいソリューションを作成できますが、実際のソリューションを最適化することが最善の選択肢だと思います。 – ggrana

+0

これは私の方法ではありません。それはちょうど – Snowman

答えて

2

あなたがそのような何かを行うことができますので、あなたは、1つのデフォルト、あなたが作成したコンパレータをいない使用する必要があります。

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init]; 
NSEntityDescription *entity = [NSEntityDescription 
           entityForName:@"Tag" inManagedObjectContext:appDelegate.managedObjectContext]; 

[fetchRequest setEntity:entity]; 
NSSortDescriptor *lastDescriptor = 
[[[NSSortDescriptor alloc] initWithKey:@"tagName" ascending:YES comparator:^NSComparisonResult(NSString* tag1, NSString* tag2) { 

    if ([tag1 isEqualToString:@"All"]) return NSOrderedAscending; 
    if ([tag2 isEqualToString:@"All"]) return NSOrderedDescending; 

    return [tag1 compare:tag2]; 
}] autorelease];  

[fetchRequest setSortDescriptors:[NSArray arrayWithObject:lastDescriptor]]; 

編集

に同様@Andrew Madsenはあなたがコンパレータを使うことができると言ったが、私は彼があなたの質問にすでに答えているのを見ない。

あなたもセレクタを使用することができ、ちょうどリンゴのドキュメントから、私はミスを犯し、それはあなたがやっていることだと信じていたものを、あなたのモデルで比較を行うための方法を、それを実装する必要があります。

セレクタ

オブジェクトのプロパティを比較するときに使用するメソッド (caseInsensitiveCompare:またはlocalizedCompare:など)。セレクタ は、keyPathによって識別されるプロパティ の値によって実装されるメソッドを指定する必要があります。比較に使用されるセレクタには、自己と比較するオブジェクトである単一のパラメータ が渡され、 は適切なNSComparisonResult定数を返す必要があります。 (NSComparisonResult)localizedCompare - :(NSStringの*)aStringの

+0

tag1とtag2の両方が "All"の場合、コンパレータはおそらくNSOrderedSameを返さなければなりません。おそらく実際には問題ではないでしょう。 –

+0

あなたは正しいですが、私はこれがこの特定の場合には関係がないと思います。 – ggrana

+0

実際には、数字で始まるtagNamesがある場合、これは正しく動作しません。上記のコードを編集して、数字の付いたタグの上に「すべて」が表示されるようにするにはどうすればよいですか? – Snowman

1

これは、カスタム比較メソッドを使用してNSSortDescriptor自体で行うことができます。ただし、フェッチ要求を取得した後でフェッチ要求の結果をソートすることもできます。 NSArrayには-sortedArrayUsingComparator:というメソッドがあり、ブロックを使用して配列をソートすることができ、このようなカスタムソートの動作を簡単に行うことができます。例えば以下を参照してください:

NSArray *sortedResults = [results sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) { 
    NSString *tag1 = [obj1 tagName]; 
    NSString *tag2 = [obj2 tagName]; 

    BOOL tag1IsAll = [tag1 isEqualToString:@"All"]; 
    BOOL tag2IsAll = [tag2 isEqualToString:@"All"]; 
    if (tag1IsAll && !tag2IsAll) return NSOrderedAscending; 
    if (tag2IsAll && !tag1IsAll) return NSOrderedDescending; 

    return [tag1 compare:tag2]; 
}]; 
+0

与えられたデフォルトのメソッドですが、私はそれが私のUITableViewを使用しているので、NSFetchedResultsControllerにする必要があり、それは私のデータソースになります。 – Snowman

+0

ソート・ディスクリプタ・セレクタ・オプションで追加したこのメソッドをどういうわけか適用できませんか? – Snowman

+0

はい、申し訳ありません。私はあなたがNSFetchedResultsControllerを使っていることを心に留めていませんでした。私のために朝早すぎる;-)。 ggranaの答えは、NSSortDescriptorでこれと同じことをする方法を示しています。 –

関連する問題