首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >NSFetchRequest /谓词问题

NSFetchRequest /谓词问题
EN

Stack Overflow用户
提问于 2010-03-31 23:32:26
回答 3查看 7.5K关注 0票数 2

我有两个实体: Patient和Job。Patient与Job之间有一个名为“jobs”的多对多关系,Job与Patient之间有一对一关系,称为“patient”。Job具有名为“dueDate”(日期)和“completed”(BOOL)的属性,而Patient具有属性“firstName”和“lastName”(两个字符串)。

我正在尝试为我的作业创建一个fetch请求/谓词,以便我们获取所有尚未完成的作业(即completed == NO),并按患者姓名对它们进行划分。下面是我的代码:

代码语言:javascript
复制
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方法:

代码语言:javascript
复制
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];

这似乎不管用。我是不是走错路了?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-03-31 23:53:37

首先,您似乎没有将sortDescriptors附加到fetchRequests。这可能与问题有关,也可能与问题无关。

其次,你可以用一种更简单的方式来完成这件事。如下所示:

代码语言:javascript
复制
sectionNameKeyPath:@"patient.name"

"name“应该是Patient对象的属性或方法。实现这一点的一种简单方法是在patient上使用一个类别方法:

代码语言:javascript
复制
- (NSString *)name {
    return [NSString stringWithFormat:@"%@ %@", self.firstName, self.lastName];
}

实际上,你不能用这么简单的东西来实现你的目的,请阅读mzarra的答案以获得正确的答案。NSFetchedResultsController有这样的批判性评论:

如果控制器生成节,则数组中的第一个排序描述符用于将对象分组为节;其键必须与sectionNameKeyPath相同,或者使用其键的相对顺序必须与使用sectionNameKeyPath的顺序相匹配。

但是,你不能对方法调用的结果进行排序,你需要一个对象的属性。因此,最好的办法可能就是在"patient“上设置一个"name”属性,并将该属性用于排序和sectionNameKeyPath。

票数 3
EN

Stack Overflow用户

发布于 2010-04-01 00:14:19

它怎么会不工作呢?它有助于描述您所看到的结果。

您没有将排序描述符添加到NSFetchRequest中,至少在您提供的示例中是这样。

您的排序描述符无效。Patient似乎是一个关系,因此对该关系进行排序将不起作用。您可能希望执行如下排序:

代码语言:javascript
复制
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提供的缓存,而不是假设该部分中将有一行:

代码语言:javascript
复制
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section 
{
    id sectionInfo = [[fetchedResultsController sections] objectAtIndex:section];
    return [sectionInfo name];
}

最后,如果您希望该节真正显示“姓,名”格式,那么您将需要在作为fullNamePatient实体上创建non-transient派生值属性,以便您可以基于它创建缓存。然后,只要名字或姓氏发生更改,就需要更新这个派生的值。

票数 6
EN

Stack Overflow用户

发布于 2010-04-01 00:16:44

除了没有将您的sortDescriptors赋给您的fetchRequest之外,我认为您的谓词也有问题。由于您正在处理核心数据,因此"completed“属性的布尔值存储在NSNumber的一个实例中。下面这样的谓词会更好:

代码语言:javascript
复制
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"completed = %@", [NSNumber numberWithBool:NO]];
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2554266

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档