2013-04-08 140 views
14

我是新的核心數據,並試圖找出如何在我的NSFetchedResultsController中創建自定義sectionNameKeyPath。我有一個被稱爲acctPeriod的屬性的託管對象。這是一個NSString。我想根據此字段的前4個字符創建部分。前4個字符代表會計期間的年份,不需要保存。自定義核心數據SectionNameKeyPath

我已經瀏覽了這個網站,看過有關瞬態屬性的帖子,但我似乎無法讓他們工作。基本上我想要這個,然後爲我的sectionNameKeyPath分配periodYear

@dynamic periodYear; 

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

任何幫助,將不勝感激。

**更新: 使用Martin R.答案,我能夠讓它按預期工作。

- (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; 
} 

回答

26

下面應該工作:實現periodYear方法(將在您的被管理對象子類的類擴展中使用 作爲「段名稱關鍵路徑」):

@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爲獲取結果控制器:

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定義爲管理對象的臨時屬性。 在這種情況下,它也不會被存儲在數據庫中,但可以按照需求計算並緩存值的方式來實現。

Apple開發者庫中的DateSectionTitles示例項目演示了這是如何工作的。

+0

好的,這很好。我之前嘗試過,但問題是,我只是試圖加載我的實體,acctPeriod 1,並按periodYear排序。所以我使用 [fetchRequest setPropertiesToFetch:[NSArray arrayWithObjects:[entityProperties objectForKey:@「acctPeriod」],nil]]; 似乎沒有工作。我試圖把periodYear作爲entityProperty,但我知道它不是。我得到這個錯誤:'無效的keypath periodYear傳遞給setPropertiesToFetch:'任何想法? – theDVUSone 2013-04-09 00:08:58

+0

@theDVUSone:如果您使用'propertiesToFetch',那麼您可能必須將'periodYear'定義爲transient屬性並將其添加到'propertiesToFetch'。我沒有嘗試過,但這就是我所假設的。 – 2013-04-09 04:59:12

+0

我在聲明執行getter的@property時犯了錯誤。這個解決方案或多或少指出它應該只是一個方法聲明。 – JLust 2014-06-11 23:43:09

8

我建議不要使用瞬時屬性作爲sectionNameKeyPath,因爲它會導致斷裂的只是這樣的屬性可以被用作部分路徑的讀取請求獲得的所有對象。
您最好定義一個year的持久性屬性,並將其用作sectionNameKeyPath
設置你FRC sectionNameKeyPathyear像這樣:

[[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest 
            managedObjectContext:self.managedObjectContext 
             sectionNameKeyPath:@"year" 
               cacheName:nil/*your chioce*/]; 

顯示部分名稱,如表中的冠軍,實現:

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