NSFetchRequest / 谓词问题
我有两个实体:患者和工作。患者与作业具有一对多关系,称为“作业”,而作业与患者具有一对一关系,称为“患者”。 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
怎么不工作呢?它有助于描述您所看到的结果。
您没有将排序描述符添加到 NSFetchRequest 中,至少在您提供的示例中是这样。
您的排序描述符无效。看来
Patient
是一种关系,因此根据该关系进行排序将不起作用。您可能希望进行如下排序:您不需要需要在返回 id 时强制转换
[fetchedResultsController objectAtIndexPath:indexPath]
。您从对
[fetchedResultsController objectAtIndexPath:indexPath]
的调用中得到什么?在这里放置一个断点并检查值并确保您返回的是 NSManagedObject 而不是 nil。在该方法中放置断点也将确认您正在被调用。您的 secondaryKeypathName 将无法像上面提到的那样工作。您可能希望将其设置为
@"patent.lastName"
,以便它与我上面描述的初始排序相匹配。您的
-tableView: titleForHeaderInSection:
应该访问由NSFetchedResultsController
提供的缓存,而不是假设该部分中将会有一行:最后,如果您希望该部分真正显示“姓氏,名字”格式,那么您需要在您的
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: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 aNSManagedObject
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 theNSFetchedResultsController
instead of assuming that there is going to be a row in the section: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 thefullName
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.首先,您似乎没有将 sortDescriptors 附加到 fetchRequests。这可能与问题有关,也可能无关。
其次,您可以通过更简单的方式完成此任务。像这样:
“name”应该是 Patient 对象的属性或方法。实现这一点的一个简单方法是对病人使用一个类别方法:
实际上,你不能用这么简单的东西来实现你的目的,请阅读 mzarra 的答案以获得正确的答案。 NSFetchedResultsController 有这样的批评:
但是,您无法对方法调用的结果进行排序,您需要对象的属性。因此,最好的选择可能是在“病人”上有一个“名称”属性,并使用该属性进行排序和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:
"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:
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:
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.
除了不将 sortDescriptor 分配给 fetchRequest 之外,我相信您的谓词也有问题。由于您正在处理核心数据,因此“completed”属性的布尔值存储在 NSNumber 的实例中。像下面的谓词这样的东西会更好:
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: