3

「プレーヤー」と呼ばれるエンティティを取得する NSFetchRequest があり、結果を次の順序で 3 つの属性で並べ替えます。

  1. 「sendingoffOffence」という属性がnilかどうか
  2. 「team.homeMatch」のエンティティの関係が nil かどうか
  3. 「number」属性の文字列を昇順にソートしたい。

基本的には、レッドカード (「sendingOffOffence」が nil でない) を持っているすべてのプレーヤーをリストの一番上に表示し、そのプレーヤーがホームチームにいるかどうかでセットを並べ替え、次に最後に、オフェンス グループのチームの選手のセットを背番号で並べ替えます。

そのため、フェッチ リクエストで次のコードを使用します。

// Set the entity for the fetch request
NSEntityDescription *entity = [NSEntityDescription
                               entityForName:@"Player"
                               inManagedObjectContext:self.match.managedObjectContext];
[fetchRequest setEntity:entity];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"match == %@", self.match];
[fetchRequest setPredicate:predicate];

// Sort the results

// Sort according to whether the user has a red card / sendingOffOffence
NSSortDescriptor *hasRedCard = [[NSSortDescriptor alloc] initWithKey:@"sendingoffOffence" ascending:NO];

// Sort according to whether the user is on the home team or not
NSSortDescriptor *isHomeTeam = [[NSSortDescriptor alloc] initWithKey:@"team.homeMatch" ascending:NO];

// Sort according to the player's jersey numbers
NSSortDescriptor *number     = [[NSSortDescriptor alloc] initWithKey:@"number" ascending:YES selector:@selector(localizedStandardCompare:)];

[fetchRequest setSortDescriptors:@[hasRedCard, isHomeTeam, number]];

// Set the amount of records to retrieve from the database
[fetchRequest setFetchBatchSize:20];

NSFetchedResultsController *theFetchedResultsController =
    [[NSFetchedResultsController alloc]
     initWithFetchRequest:fetchRequest
     managedObjectContext:self.match.managedObjectContext
     sectionNameKeyPath:nil
     cacheName:@"MatchCache"]

ただし、上記のコードを実行すると、次の結果が得られます。

レッドカードソート イエローカードソート

赤いカード セクションに次の順序を表示する必要があるため、この並べ替え順序は間違っています。

  • 11 - ホーム
  • 12 - ホーム
  • 0 - 退席中
  • 11 - アウェイ
  • 21 - アウェイ

そしてイエローカードのセクションでは:

  • 1 - ホーム
  • 2 - ホーム
  • 99 - ホーム
  • 1 - 離席中
  • 31 - アウェイ

イエロー カード セクションは正しくソートされているように見えますが、レッド カード セクションは非常に奇妙な動作を示しており、まったくソートされていないように見えます。

レッドカードセクションが正しくソートされない理由について、私はかなり困惑しています - 何か考えはありますか? コア データに依存して優先順位を取得するのではなく、これらのオブジェクトをメモリ内で並べ替える必要がありますか?

これは、SQL ベースの永続ストアを使用するコア データ アプリケーションであることに注意してください。

アップデート

以下は、私のフェッチでコア データが使用している SQL ステートメントです。

CoreData: annotation: fetch using NSSQLiteStatement <0x11c77cd0> on entity 'SPlayer' with 
sql text 'SELECT t0.Z_ENT, t0.Z_PK FROM ZFSMANAGEDOBJECT t0 LEFT OUTER JOIN ZSTEAM t1 ON 
t0.ZTEAM = t1.Z_PK WHERE ( t0.ZMATCH1 = ? AND  t0.Z_ENT = ?) ORDER BY 
t0.ZSENDINGOFFOFFENCE DESC, t1.ZHOMEMATCH DESC, t0.ZNUMBER COLLATE NSCollateFinderlike '

4

2 に答える 2

3

これは適切に適用されていない行です (RED カードの場合):

NSSortDescriptor *isHomeTeam = [[NSSortDescriptor alloc] initWithKey:@"team.homeMatch" ascending:NO];

データ モデルといくつかのサンプル データを見ないと、なぜこれが適切に並べ替えられないのかを判断するのは困難です。これにより、最初に NIL 値が配置され、次に適切な値が配置されると思います (したがって、NO の昇順で並べ替えると、YELLOW カードの場合と同じようになります)。

私がこのような状況にあった場合、並べ替え順序とこれらの team.homeMatch プロパティに関する私の仮定を確認します。これが唯一のソート記述であるテストを行います。

次に、RED/YELLOW カードの状態の違いに注目してください。

于 2013-06-27T12:23:33.240 に答える
1

このようにNSFetchedResultsControllerなしで実行しました....

NSEntityDescription *entity = [NSEntityDescription
                               entityForName:@"Player"
                               inManagedObjectContext:self.match.managedObjectContext];
[fetchRequest setEntity:entity];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"match == %@", self.match];
[fetchRequest setPredicate:predicate];

// Sort the results

// Sort according to whether the user has a red card / sendingOffOffence
NSSortDescriptor *hasRedCard = [[NSSortDescriptor alloc] initWithKey:@"sendingoffOffence" ascending:NO];

// Sort according to whether the user is on the home team or not
NSSortDescriptor *isHomeTeam = [[NSSortDescriptor alloc] initWithKey:@"team.homeMatch" ascending:NO];


[fetchRequest setSortDescriptors:@[hasRedCard, isHomeTeam]];

// Set the amount of records to retrieve from the database
[fetchRequest setFetchBatchSize:20];

NSArray *resultArray = [self.match.managedObjectContext executeFetchRequest:request error:&error];


NSSortDescriptor *number     = [[NSSortDescriptor alloc] initWithKey:@"number" ascending:YES selector:@selector(localizedStandardCompare:)];
    NSArray *sortedArray = [resultArray sortedArrayUsingDescriptors:[NSArray arrayWithObjects:number, nil]];
于 2013-06-27T12:26:37.573 に答える