我有两个实体: Patient和Job。Patient与Job之间有一个名为“jobs”的多对多关系,Job与Patient之间有一对一关系,称为“patient”。Job具有名为“dueDate”(日期)和“completed”(BOOL)的属性,而Patient具有属性“firstName”和“lastName”(两个字符串)。
我正在尝试为我的作业创建一个fetch请求/谓词,以便我们获取所有尚未完成的作业(即completed == 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];这似乎不管用。我是不是走错路了?
发布于 2010-03-31 23:53:37
首先,您似乎没有将sortDescriptors附加到fetchRequests。这可能与问题有关,也可能与问题无关。
其次,你可以用一种更简单的方式来完成这件事。如下所示:
sectionNameKeyPath:@"patient.name""name“应该是Patient对象的属性或方法。实现这一点的一种简单方法是在patient上使用一个类别方法:
- (NSString *)name {
return [NSString stringWithFormat:@"%@ %@", self.firstName, self.lastName];
}实际上,你不能用这么简单的东西来实现你的目的,请阅读mzarra的答案以获得正确的答案。NSFetchedResultsController有这样的批判性评论:
如果控制器生成节,则数组中的第一个排序描述符用于将对象分组为节;其键必须与sectionNameKeyPath相同,或者使用其键的相对顺序必须与使用sectionNameKeyPath的顺序相匹配。
但是,你不能对方法调用的结果进行排序,你需要一个对象的属性。因此,最好的办法可能就是在"patient“上设置一个"name”属性,并将该属性用于排序和sectionNameKeyPath。
发布于 2010-04-01 00:14:19
它怎么会不工作呢?它有助于描述您所看到的结果。
您没有将排序描述符添加到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;不需要强制转换[fetchedResultsController objectAtIndexPath:indexPath],因为它返回id。
从对[fetchedResultsController objectAtIndexPath:indexPath]的调用中您得到了什么?在这里放置一个断点并检查其值,并确保返回的是NSManagedObject而不是nil。在该方法中放置一个断点也将确认您正在被调用。
您的secondKeypathName将不会像上面提到的那样工作。您可能希望将其设置为@"patient.lastName",以便与我上面描述的初始排序相匹配。
您的-tableView: titleForHeaderInSection:应该访问NSFetchedResultsController提供的缓存,而不是假设该部分中将有一行:
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
id sectionInfo = [[fetchedResultsController sections] objectAtIndex:section];
return [sectionInfo name];
}最后,如果您希望该节真正显示“姓,名”格式,那么您将需要在作为fullName的Patient实体上创建non-transient派生值属性,以便您可以基于它创建缓存。然后,只要名字或姓氏发生更改,就需要更新这个派生的值。
发布于 2010-04-01 00:16:44
除了没有将您的sortDescriptors赋给您的fetchRequest之外,我认为您的谓词也有问题。由于您正在处理核心数据,因此"completed“属性的布尔值存储在NSNumber的一个实例中。下面这样的谓词会更好:
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"completed = %@", [NSNumber numberWithBool:NO]];https://stackoverflow.com/questions/2554266
复制相似问题