NSFetchRequest / 谓词问题

发布于 2024-08-27 10:06:30 字数 1560 浏览 8 评论 0原文

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

我正在尝试为我的 NSFetchedResultsController 创建一个获取请求/谓词,我们抓取所有尚未完成的作业(即已完成==否)并按患者姓名对它们进行分段。这是我的代码:

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];

这似乎不起作用。我是否以错误的方式处理这个问题?

I have two entities: Patient and Job. Patient has a to-many relationship to Job called 'jobs' and Job has a to-one relationship to Patient called 'patient'. Job has attributes called 'dueDate' (Date) and 'completed' (BOOL) and Patient has attributes 'firstName' and 'lastName' (both Strings).

I am trying to create a fetch request / predicate for my NSFetchedResultsController that we grab all Jobs that have not been completed (i.e. completed == NO) and section them by Patient name. Here is my code:

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"];

Here is my titleForHeaderInSection method:

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];

This doesn't seem to work. Am I going about this the wrong way?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

不及他 2024-09-03 10:06:30

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

您没有将排序描述符添加到 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。在该方法中放置断点也将确认您正在被调用。

您的 secondaryKeypathName 将无法像上面提到的那样工作。您可能希望将其设置为@"patent.lastName",以便它与我上面描述的初始排序相匹配。

您的 -tableView: titleForHeaderInSection: 应该访问由 NSFetchedResultsController 提供的缓存,而不是假设该部分中将会有一行:

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

最后,如果您希望该部分真正显示“姓氏,名字”格式,那么您需要在您的 Patient 实体上创建一个非瞬态派生值属性是fullName,以便您可以基于它创建缓存。每当名字或姓氏发生更改时,都需要更新此派生值。

How is it not working? It helps to describe what results you are seeing.

You are not adding your sort descriptors to your NSFetchRequest, at least in the sample you provided.

Your sort descriptors are ineffective. It appears that Patient is a relationship so sorting against the relationship will not work. You would want to do a sort like the following:

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;

You do not need to cast [fetchedResultsController objectAtIndexPath:indexPath] as it returns id.

What are you getting back from the call to [fetchedResultsController objectAtIndexPath:indexPath]? Put a breakpoint here and check the value and make sure you are getting back a NSManagedObject instead of nil. Putting a breakpoint in that method will also confirm that you are getting called.

Your secondKeypathName will not work as mentioned above. You probably want to set it to @"patient.lastName" so that it will match the initial sort I described above.

Your -tableView: titleForHeaderInSection: should be accessing the cache provided by the NSFetchedResultsController instead of assuming that there is going to be a row in the section:

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

Finally, if you want the section to truly display the "lastname, firstname" format then you will need to create a non-transient derived value property on your Patient entity that is the fullName so that you can create your cache based on it. This derived value would then need to be updated any time that the first name or last name were changed.

GRAY°灰色天空 2024-09-03 10:06:30

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

其次,您可以通过更简单的方式完成此任务。像这样:

sectionNameKeyPath:@"patient.name"

“name”应该是 Patient 对象的属性或方法。实现这一点的一个简单方法是对病人使用一个类别方法:

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

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

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

但是,您无法对方法调用的结果进行排序,您需要对象的属性。因此,最好的选择可能是在“病人”上有一个“名称”属性,并使用该属性进行排序和sectionNameKeyPath。

First, you don't seem to attach the sortDescriptors to fetchRequests. This may or may not be connected with the problem.

Second, you can accomplish this in an easier way. Make it like this:

sectionNameKeyPath:@"patient.name"

"name" should be a property or method of the Patient object. An easy way to implement this would be to have a category method on patient:

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

Actually, you can't accomplish your purpose with something as simple as this, read mzarra's answer for correct answer. NSFetchedResultsController has this critical comment:

If the controller generates sections, the first sort descriptor in the array is used to group the objects into sections; its key must either be the same as sectionNameKeyPath or the relative ordering using its key must match that using sectionNameKeyPath.

But, you cannot sort on the results of a method call, you'd need a property of the object. So, your best bet is probably just have a "name" property on "patient", and use that property for both sorting and sectionNameKeyPath.

夏日浅笑〃 2024-09-03 10:06:30

除了不将 sortDescriptor 分配给 fetchRequest 之外,我相信您的谓词也有问题。由于您正在处理核心数据,因此“completed”属性的布尔值存储在 NSNumber 的实例中。像下面的谓词这样的东西会更好:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"completed = %@", [NSNumber numberWithBool:NO]];

In addition to not assigning your sortDescriptors to your fetchRequest, I believe you have a problem with your predicate. Since you are dealing with Core Data, the boolean value for your "completed" attribute is stored in an instance of NSNumber. Something like the predicate below would be better:

NSPredicate *predicate = [NSPredicate predicateWithFormat:@"completed = %@", [NSNumber numberWithBool:NO]];
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文