iPhone 按日期排序核心数据 NSFetchedResultsController
Posted
技术标签:
【中文标题】iPhone 按日期排序核心数据 NSFetchedResultsController【英文标题】:iPhone by-date sorting core data NSFetchedResultsController 【发布时间】:2010-12-05 18:11:27 【问题描述】:我正在开发的程序是“CoreDataBooks”的修改版本,取自 Apple iPhone 示例代码。在“CoreDataBooks”中有一个作者列表,其中一些作者有多本书。设置导航控制器,按作者姓名划分部分。在每个部分中,都有每个作者的书籍列表。
所以我使用了这段代码,并试图制作一个按部分排列的名称列表。我的实体被称为“病人”。每个实体都有属性 myDate 和 myName 以及其他一些属性。我想按 myDate 排列部分,每个部分中都有一个名称列表,所有这些都具有相同的日期。
我在使用 NSFetchedResultsController 方法时遇到了困难。当使用日期选择器创建日期时,它们都有一个时间戳。此时间戳使它们不同,如果您在 sectionNameKeyPath 方法中按 myDate 排序,它们将被放置到单独的部分中。
我在网上进行了相当广泛的搜索,并提出了以下解决方案。您创建另一个瞬态属性,一个 NSString,然后使用它对部分进行排序。这是通过创建一个日期格式化程序来完成的,如下所示。我包括了我的 NSString 的 setter,以及 NSFetchedResultsController 方法。
任何帮助将不胜感激。
- (NSFetchedResultsController *)fetchedResultsController
if (fetchedResultsController != nil)
return fetchedResultsController;
PatientsAppDelegate*appDelegate=[[UIApplication sharedApplication]delegate];
NSManagedObjectContext*managedObjectContext=appDelegate.managedObjectContext;
// Create and configure a fetch request with the Book entity.
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Patient" inManagedObjectContext:managedObjectContext];
[fetchRequest setEntity:entity];
// Create the sort descriptors array.
NSSortDescriptor *dateDescriptor = [[NSSortDescriptor alloc] initWithKey:@"myDate" ascending:YES];
NSSortDescriptor *nameDescriptor = [[NSSortDescriptor alloc] initWithKey:@"myName" ascending:YES];
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:dateDescriptor, nameDescriptor, nil];
[fetchRequest setSortDescriptors:sortDescriptors];
// NSLog(@"%@",myFormattedDate);
// Create and initialize the fetch results controller.
NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:managedObjectContext
sectionNameKeyPath:@"transactionDay"
cacheName:@"Root"];
self.fetchedResultsController = aFetchedResultsController;
fetchedResultsController.delegate = self;
// Memory management.
[aFetchedResultsController release];
[fetchRequest release];
[dateDescriptor release];
[nameDescriptor release];
[sortDescriptors release];
return fetchedResultsController;
- (NSString *)transactionDay
[self willAccessValueForKey:@"transactionDay"];
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"MM dd,yyyy"];
NSString*someString=[dateFormatter stringFromDate:[self valueForKey:@"myDate"]];
[self didAccessValueForKey:@"transactionDay"];
return someString;
我得到的当前错误是“实体 Patient 不符合键“transactionDay”的键值编码”
再次感谢。
【问题讨论】:
不要使用“[code]”标签。使用“101010”按钮格式化代码。 【参考方案1】:在指定sectionNameKeyPath
时,您必须包含要应用瞬态属性的实体属性(即entityAttribute.transientAttribute
)。因此,如果您有一个实体Patient
,其属性myDate
类型为NSDate
:
// Create and initialize the fetch results controller.
NSFetchedResultsController *aFetchedResultsController =
[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest
managedObjectContext:managedObjectContext
sectionNameKeyPath:@"myDate.transactionDay"
cacheName:@"Root"];
可以在Patient
实现文件中定义瞬态属性,方法是在顶部添加以下内容:
@implementation NSDate (TransactionDayFormat)
- (NSString *)transactionDay
NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
[dateFormatter setDateFormat:@"MM dd,yyyy"];
NSString*someString=[dateFormatter stringFromDate:self];
return someString;
@end
@implementation Patient
...
transactionDay
将进一步处理您的myDate
属性,允许您将部分指定为更严格的格式。请注意,NSDateFormatter
是一个非常庞大的初始化对象,因此为了提高效率,提前声明它并稍后引用它可能是值得的。
【讨论】:
【参考方案2】:-transactionDay
方法应该是您在 Patient
类上实现的属性,然后这个类(我猜是视图控制器)可以选择基于它进行排序或分区。
【讨论】:
【参考方案3】:听起来您正在尝试使用尚未在 Patient 的对象模型中声明为属性的 sectionNameKeyPath 来初始化 fetchedResultsController。
您能否确认 transactionDay 在您的 Patient 对象模型中被定义为 NSString 属性?
此外,这听起来有点绕圈子来实现您想要实现的目标。也许您应该尝试从您的 NSDate 属性中删除时间戳?我对 SO 进行了快速搜索,可以找到删除 NSDate 时间戳的可能解决方案
-(NSDate *)dateWithOutTime:(NSDate *)datDate
if( datDate == nil )
datDate = [NSDate date];
NSDateComponents* comps = [[NSCalendar currentCalendar] components:NSYearCalendarUnit|NSMonthCalendarUnit|NSDayCalendarUnit fromDate:datDate];
return [[NSCalendar currentCalendar] dateFromComponents:comps];
问题的链接是Removing time components from an NSDate object using Objective C/Cocoa
【讨论】:
以上是关于iPhone 按日期排序核心数据 NSFetchedResultsController的主要内容,如果未能解决你的问题,请参考以下文章
使用 FetchedResultsController 按日期对核心数据进行排序