自定义核心数据 SectionNameKeyPath [英] Custom Core Data SectionNameKeyPath

查看:17
本文介绍了自定义核心数据 SectionNameKeyPath的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是核心数据的新手,正在尝试弄清楚如何在我的 NSFetchedResultsController 中创建自定义的 sectionNameKeyPath.我有一个具有名为 acctPeriod 的属性的托管对象.它是一个 NSString.我想根据该字段的前 4 个字符创建部分.前4个字符代表会计期间的年份,不需要保存.

I am new at core data and am trying to figure out how to create a custom sectionNameKeyPath in my NSFetchedResultsController. I have a managed object with an attribute called acctPeriod. It is a NSString. I want to create sections based on the first 4 characters of this field. The first 4 characters represent the year of the accounting period and doesn't need to be saved.

我浏览了这个网站,看到了关于瞬态属性的帖子,但我似乎无法让它们工作.基本上我想要这个,然后为我的 sectionNameKeyPath 分配 periodYear.

I have gone through this site and have seen posts about transient attributes but I can't seem to get them to work. Basically I want this and then assign periodYear for my sectionNameKeyPath.

@dynamic periodYear;

-(NSString *)periodYear
{
    return [self.acctPeriod substringToIndex:4];
}

任何帮助将不胜感激.

**更新:使用 Martin R. 的回答,我能够让它按预期工作.

**UPDATE: Using Martin R. answer, I was able to get it to work as expected.

- (NSFetchedResultsController *)fetchedResultsController
{
if (_fetchedResultsController != nil) {
    return _fetchedResultsController;
}

NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];

// Edit the entity name as appropriate.
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Billing" inManagedObjectContext:self.managedObjectContext];
[fetchRequest setEntity:entity];

// Set the batch size to a suitable number.
[fetchRequest setFetchBatchSize:20];

// Edit the sort key as appropriate.
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"acctPeriod" ascending:NO];
NSArray *sortDescriptors = @[sortDescriptor];

//Predicate
NSPredicate *pred = [NSPredicate predicateWithFormat:@"clients = %@", self.client];
NSLog(@"%@",pred);

//[fetchRequest setResultType:NSDictionaryResultType];
//[fetchRequest setReturnsDistinctResults:YES];

[fetchRequest setPredicate:pred];
[fetchRequest setSortDescriptors:sortDescriptors];

NSFetchedResultsController *aFetchedResultsController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:self.managedObjectContext sectionNameKeyPath:@"periodYear" cacheName:nil];
aFetchedResultsController.delegate = self;
self.fetchedResultsController = aFetchedResultsController;

NSError *error = nil;
if (![self.fetchedResultsController performFetch:&error])
{
    NSLog(@"Unresolved error %@, %@", error, [error userInfo]);
    abort();
}

return _fetchedResultsController;  
}

推荐答案

以下应该有效:实现 periodYear 方法(将使用作为节名称键路径")在您的托管对象子类的类扩展中:

The following should work: Implement the periodYear method (which will be used as "section name key path") in a class extension of your managed object subclass:

@interface Event (AdditionalMethods)
- (NSString *)periodYear;
@end

@implementation Event (AdditionalMethods)
- (NSString *)periodYear {
    return [self.acctPeriod substringToIndex:4];
}
@end

确保acctPeriod用作获取请求的第一个(或唯一的)排序描述符:

NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"acctPeriod" ascending:YES];
NSArray *sortDescriptors = @[sortDescriptor];
[fetchRequest setSortDescriptors:sortDescriptors];

使用 periodYear 作为 sectionNameKeyPath 获取的结果控制器:

Use periodYear as sectionNameKeyPath for the fetched results controller:

NSFetchedResultsController *_fetchedResultsController = [[NSFetchedResultsController alloc]
                  initWithFetchRequest:fetchRequest 
                   managedObjectContext:self.managedObjectContext 
                     sectionNameKeyPath:@"periodYear"
                              cacheName:nil];
_fetchedResultsController.delegate = self;
self.fetchedResultsController = _fetchedResultsController;

最后添加默认的titleForHeaderInSection方法:

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

或者,您可以将periodYear 定义为托管对象的transient 属性.在这种情况下,它也不会存储在数据库中,但可以通过按需计算并缓存值的方式来实现.

Alternatively, you can define periodYear as transient attribute of the managed object. It will also not be stored in the database in that case, but can be implemented in a way that the value is calculated on demand and cached.

DateSectionTitles 示例项目来自Apple Developer Library 演示了这是如何工作的.

The DateSectionTitles sample project from the Apple Developer Library demonstrates how this works.

这篇关于自定义核心数据 SectionNameKeyPath的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆