2

患者と仕事の 2 つのエンティティがあります。患者は「ジョブ」と呼ばれるジョブと対多の関係を持ち、ジョブは「患者」と呼ばれる患者と対一の関係を持ちます。Job には「dueDate」(Date) と「completed」(BOOL) という属性があり、Patient には属性「firstName」と「lastName」(どちらも文字列) があります。

NSFetchedResultsController のフェッチ要求/述語を作成しようとしています。完了していないすべてのジョブを取得し (つまり、完了 == NO)、それらを患者名でセクション化します。これが私のコードです:

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Job" inManagedObjectContext:moc];
[fetchRequest setEntity:entity];

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(completed == NO)"];
[fetchRequest setPredicate:predicate];

NSSortDescriptor *patientDescriptor = [[NSSortDescriptor alloc] initWithKey:@"patient" ascending:YES];
NSSortDescriptor *dueDateDescriptor = [[NSSortDescriptor alloc] initWithKey:@"dueDate" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:patientDescriptor, dueDateDescriptor, nil];

NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:moc sectionNameKeyPath:@"patient" cacheName:@"Jobs"];

ここに私の titleForHeaderInSection メソッドがあります:

NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:section];
NSString *firstName = [[(Job *)[fetchedResultsController objectAtIndexPath:indexPath] patient] firstName];
NSString *lastName = [[(Job *)[fetchedResultsController objectAtIndexPath:indexPath] patient] lastName];

return [NSString stringWithFormat:@"%@ %@", firstName, lastName];

これはうまくいかないようです。私はこれについて間違った方法で進んでいますか?

4

3 に答える 3

6

どのように機能していませんか?どのような結果が得られたかを説明するのに役立ちます。

少なくとも提供したサンプルでは、​​ソート記述子を NSFetchRequest に追加していません。

ソート記述子が無効です。関係があるように見えるPatientので、関係に対するソートは機能しません。次のような並べ替えを行います。

NSSortDescriptor *lastNameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"patient.lastName" ascending:YES];
NSSortDescriptor *firstNameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"patient.firstName" ascending:YES];
NSSortDescriptor *dueDateDescriptor = [[NSSortDescriptor alloc] initWithKey:@"dueDate" ascending:NO];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects: lastNameDescriptor, firstNameDescriptor, dueDateDescriptor, nil];

[fetchRequest setSortDescriptors:sortDescriptors];

[lastNameDescriptor release], lastNameDescriptor = nil;
[firstNameDescriptor release], firstNameDescriptor = nil;
[dueDateDescriptor release], dueDateDescriptor = nil;

id を返すため、キャストする必要はありません。[fetchedResultsController objectAtIndexPath:indexPath]

への通話から何を返しています[fetchedResultsController objectAtIndexPath:indexPath]か? ここにブレークポイントを置き、値を確認してNSManagedObject、nil ではなく a が返されていることを確認してください。そのメソッドにブレークポイントを設定すると、呼び出されていることも確認できます。

上記のように secondKeypathName は機能しません。@"patient.lastName"上記で説明した最初の並べ替えと一致するように、 おそらく に設定する必要があります。

セクションに行があると想定するのではなく、-tableView: titleForHeaderInSection:によって提供されるキャッシュにアクセスする必要があります。NSFetchedResultsController

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section 
{
    id sectionInfo = [[fetchedResultsController sections] objectAtIndex:section];
    return [sectionInfo name];
}

最後に、セクションに「姓、名」形式を正しく表示する場合は、エンティティに非一時的な派生値プロパティを作成して、それに基づいてキャッシュを作成できるようにする必要があります。この派生値は、名または姓が変更されるたびに更新する必要があります。PatientfullName

于 2010-03-31T16:14:18.630 に答える
3

まず、sortDescriptors を fetchRequests にアタッチしていないようです。これは、問題に関連している場合とそうでない場合があります。

第二に、これをより簡単な方法で実現できます。次のようにします。

sectionNameKeyPath:@"patient.name"

「name」は、Patient オブジェクトのプロパティまたはメソッドである必要があります。これを実装する簡単な方法は、患者にカテゴリ メソッドを設定することです。

- (NSString *)name {
    return [NSString stringWithFormat:@"%@ %@", self.firstName, self.lastName];
}

実際には、このような単純なことで目的を達成することはできません。正解についてはmzarraの回答を読んでください。NSFetchedResultsController には、次の重要なコメントがあります。

コントローラーがセクションを生成する場合、配列内の最初のソート記述子を使用して、オブジェクトをセクションにグループ化します。そのキーは sectionNameKeyPath と同じであるか、そのキーを使用する相対順序が sectionNameKeyPath を使用する順序と一致する必要があります。

ただし、メソッド呼び出しの結果をソートすることはできません。オブジェクトのプロパティが必要です。したがって、最善の策は、おそらく「患者」に「名前」プロパティを設定し、そのプロパティを並べ替えと sectionNameKeyPath の両方に使用することです。

于 2010-03-31T15:53:37.400 に答える
2

sortDescriptors を fetchRequest に割り当てないことに加えて、述語に問題があると思います。コア データを扱っているため、「完了」属性のブール値は NSNumber のインスタンスに格納されます。以下の述語のようなものがよいでしょう。

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"completed = %@", [NSNumber numberWithBool:NO]];
于 2010-03-31T16:16:44.317 に答える