2013-04-08 21 views
14

Ben çekirdek verilerine yeniyim ve benim NSFetchedResultsController bir özel sectionNameKeyPath nasıl oluşturulacağını anlamaya çalışıyorum. acctPeriod adlı bir özniteliği olan yönetilen bir nesnem var. Bu NSString'dur. Bu alanın ilk 4 karakterine dayalı bölümler oluşturmak istiyorum. İlk 4 karakter, hesap döneminin yılını temsil eder ve kaydedilmeye gerek yoktur.Özel Çekirdek Veri SectionNameKeyPath

ben bu site üzerinden gitmiş ve geçici özellikler hakkında Mesajları gördük ama onları işe almak gibi olamaz. Temel olarak bunu istiyorum ve sectionNameKeyPath benim periodYear atayın.

@dynamic periodYear; 

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

Herhangi bir yardım için teşekkür ederiz.

** GÜNCELLEME: Martin R. cevabı kullanarak, beklendiği gibi işe almak başardı. o özellik bölüm yolu olarak kullanılabilecek sadece bu yüzden getirme isteği ile elde tüm nesneleri faylanma sonuçlanacaktır olarak

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

cevap

26

çalışmalıdır: periodYear yöntemi uygulamak

: yönetilen nesne alt sınıfının bir sınıf uzantısında ("bölümü adı anahtar yolu" olarak kullanılacağı)

acctPeriod getirme isteğinin ilk (veya tek) sıralama tanımlayıcı olarak kullanıldığından emin olun:

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

Kullanım periodYear getirilen sonuçlar denetleyicisi için sectionNameKeyPath olarak:

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

Ve nihayet varsayılan titleForHeaderInSection yöntemini ekleyin:

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

Alternatif olarak, yönetilen nesnenin geçici özniteliği olarak tanımlayabilirsiniz. Ayrıca, bu durumda veritabanında saklanmayacaktır, ancak değer talep üzerine ve önbelleğe kaydedilmiş şekilde hesaplanabilir.

Apple Developer Library'den gelen DateSectionTitles örnek projesi bunun nasıl çalıştığını gösterir. Büyük çalıştı

+0

Tamam. Bunu daha önce denedim ama sorun sadece benim varlık, acctPeriod 1 yüklemek ve periodear tarafından sıralamak çalışıyorum olmasıdır.Yani kullanıyordum [fetchRequest setPropertiesToFetch: [NSArray dizisiWithObjects: [entityProperties objectForKey: @ "acctPeriod"], nil]]; Çalışmıyor gibi görünen . PeriodYear öğesini varlıkProperty olarak ayarlamaya çalıştım ama bunun olmadığını biliyorum. Bu hatayı alıyorum: 'Geçersiz keypath periodYear setPropertiesToFetch'e geçti:' Herhangi bir düşünce? – theDVUSone

+0

@theDVUSone: Eğer 'propertiesToFetch' işlevini kullanırsanız, muhtemelen 'periodYear'ı geçici öznitelik olarak tanımlamanız ve' propertiesToFetch 'öğesine eklemeniz gerekir. Denemedim, ama varsaydığım şey bu. –

+0

Bir alıcıyı uygulayan bir @property bildirme hatasını yapıyordum. Bu çözüm az ya da çok, sadece bir yöntem beyanı olması gerektiğine işaret etti. – JLust

8

Ben sectionNameKeyPath olarak geçici özelliğini kullanarak karşı tavsiye ederiz.
iyisi year bir kalıcı özellik tanımlamak ve sectionNameKeyPath olarak kullanabilirsiniz.
şöyle year size FRC sectionNameKeyPath ayarlayın:

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

tablodaki bir başlık olarak bölüm adını görüntülemek için, uygulamaya:

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