我希望有人可以就如何处理这个问题给我一些有用的建议。
我一直在尝试多种方法来根据客户端属性的自定义访问器作为第一个排序描述符,对具有 client< - >> job 关系的一组实体进行排序,然后将作业描述属性作为第二个排序描述符。
我首先尝试使用名为Client.sortValue的瞬态属性,并发现瞬态属性不能用作NSFetchedResultsController的排序描述符。所以我将属性Client.sortValue更改为非瞬态。
我从不将sortValue的值保存到持久性存储中。相反,我使用自定义访问器。显然,当运行 fetechedResultsController performFetch:方法时,不使用自定义访问器方法。当我进行日志记录时会调用它,如下面的代码所示。我可以看到,在自定义访问器中使用断点并查看堆栈跟踪就是这种情况。运行performFetch时,我没有看到它在访问器方法上中断,但是在完成日志记录时它会在访问器方法上中断。
(奇怪的是,我今天早些时候在某些情况下工作了,但其他人没有。显然我按照我希望的方式进行排序,但是在我重构我的代码以追踪其工作条件之后,我有没见过它再次起作用。)
我尝试了各种自定义访问器方法,包括以下内容:
- (NSString *) primitiveSortValue {
NSString *retVal = nil;
[self willAccessValueForKey:@"lastName"];
[self willAccessValueForKey:@"firstName"];
[self willAccessValueForKey:@"company"];
if (![self.lastName isNullString] ) retVal = [self primitiveValueForKey:@"lastName"];
else if (![self.firstName isNullString] ) retVal = [self primitiveValueForKey:@"firstName"];
else if (![self.company isNullString] ) retVal = [self primitiveValueForKey:@"company"];
else retVal = @"";
[self didAccessValueForKey:@"lastName"];
[self didAccessValueForKey:@"firstName"];
[self didAccessValueForKey:@"company"];
NSLog(@"Sort Value: %@", retVal);
return retVal;
}
在决定覆盖原始访问器方法之前,我也试过这个:
- (NSString *) sortValue {
NSString *retVal = nil;
if (![self.lastName isNullString] ) retVal = self.lastName;
else if (![self.firstName isNullString] ) retVal = self.firstName;
else if (![self.company isNullString] ) retVal = self.company;
else retVal = @"";
NSLog(@"Sort Value: %@", retVal);
return retVal;
}
这是我的fetchedResultsController方法:
#define CLIENT_SORT_KEY @"clientOfJob.sortValue"
- (NSFetchedResultsController *) fetchedResultsController {
if (fetchedResultsController != nil) {
return fetchedResultsController;
}
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription * entity = [NSEntityDescription entityForName:@"Job" inManagedObjectContext:dataInterface.managedObjectContext];
[fetchRequest setEntity:entity];
[fetchRequest setFetchBatchSize:10];
if (segmentedControl.selectedSegmentIndex == 0) { // sort by client, then job dscription
NSSortDescriptor *clientSortDescriptor = [[NSSortDescriptor alloc] initWithKey:CLIENT_SORT_KEY ascending:YES];
NSSortDescriptor *jobSortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"jobDescription" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:clientSortDescriptor, jobSortDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
NSFetchedResultsController *aFetchedResultsController =
[[NSFetchedResultsController alloc]
initWithFetchRequest:fetchRequest
managedObjectContext:dataInterface.managedObjectContext
sectionNameKeyPath:CLIENT_SORT_KEY
cacheName:nil];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;
[aFetchedResultsController release];
[fetchRequest release];
[jobSortDescriptor release];
[clientSortDescriptor release];
[sortDescriptors release];
}
else { // sort by job description
... }
NSError *error = nil;
if (![fetchedResultsController performFetch:&error]) {
NSLog(@"Unresolved Error %@, %@", error, [error userInfo]);
abort();
}
int i = 0;
for (id<NSFetchedResultsSectionInfo> sectionItem in [fetchedResultsController sections]){
NSLog(@"\n***********\nsection %d name %@\n-----------\n",i++, [sectionItem name]);
int j = 0;
for (Job *jobItem in [sectionItem objects]) {
NSLog(@"%d job: %@, client: %@\n",j, jobItem.jobDescription, jobItem.clientOfJob.sortValue);
}
}
return fetchedResultsController;
}