2013-04-08 42 views
14

Tôi mới ở dữ liệu cốt lõi và đang cố gắng tìm ra cách tạo một tùy chỉnh sectionNameKeyPath trong số NSFetchedResultsController của mình. Tôi có một đối tượng được quản lý với một thuộc tính được gọi là acctPeriod. Nó là NSString. Tôi muốn tạo các phần dựa trên 4 ký tự đầu tiên của trường này. 4 ký tự đầu tiên đại diện cho năm của kỳ kế toán và không cần phải lưu.Dữ liệu cốt lõi tùy chỉnh SectionNameKeyPath

Tôi đã đi qua trang web này và đã xem các bài đăng về các thuộc tính tạm thời nhưng tôi dường như không thể khiến chúng hoạt động. Về cơ bản tôi muốn điều này và sau đó chỉ định periodYear cho số sectionNameKeyPath của tôi.

@dynamic periodYear; 

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

Mọi trợ giúp sẽ được đánh giá cao.

** CẬP NHẬT: Sử dụng Martin R. trả lời, tôi có thể làm cho nó hoạt động như mong đợi.

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

Trả lời

26

Sau đây nên làm việc: Thực hiện các phương pháp periodYear (sẽ được sử dụng dưới dạng "đường dẫn khóa tên phần") trong một lớp mở rộng của lớp con đối tượng được quản lý của bạn:

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

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

Hãy chắc chắn rằng acctPeriod được sử dụng như mô tả đầu tiên (hoặc chỉ) sắp xếp cho các yêu cầu lấy:

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

Sử dụng periodYear như sectionNameKeyPath về kết quả lấy điều khiển:

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

Và cuối cùng thêm phương thức titleForHeaderInSection mặc định:

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

Hoặc, bạn có thể xác định periodYear làm thuộc tính tạm thời của đối tượng được quản lý. Nó cũng sẽ không được lưu trữ trong cơ sở dữ liệu trong trường hợp đó, nhưng có thể được thực hiện theo cách mà giá trị được tính theo yêu cầu và được lưu vào bộ nhớ cache.

Dự án mẫu DateSectionTitles từ Thư viện nhà phát triển Apple cho biết cách hoạt động của tính năng này.

+0

OK, điều đó đã hiệu quả. Tôi đã thử điều này trước nhưng vấn đề là tôi đang cố gắng chỉ để tải 1 trong các thực thể của tôi, acctPeriod, và sắp xếp nó theo periodYear.Vì vậy, tôi đã sử dụng [fetchRequest setPropertiesToFetch: [NSArray arrayWithObjects: [entityProperties objectForKey: @ "acctPeriod"], nil]]; có vẻ không hoạt động. Tôi đã cố gắng để đặt periodYear như entityProperty nhưng tôi biết rằng nó không phải. Tôi nhận được lỗi này: 'Khoảng thời gian đường dẫn không hợp lệYăm được chuyển đến setPropertiesToFetch:' Bất kỳ suy nghĩ nào? – theDVUSone

+0

@ theDVUSone: Nếu bạn sử dụng 'propertiesToFetch' thì có thể bạn phải định nghĩa' periodYear' làm thuộc tính tạm thời và thêm nó vào 'propertiesToFetch'. Tôi đã không thử nó, nhưng đó là những gì tôi giả định. –

+0

Tôi đã phạm sai lầm khi khai báo một @property đã triển khai trình thu thập dữ liệu. Giải pháp này ít nhiều chỉ ra rằng nó chỉ là một tuyên bố phương pháp. – JLust

8

tôi khuyên bạn nên sử dụng chống lại một tài sản thoáng qua như sectionNameKeyPath vì nó sẽ dẫn đến đứt gãy tất cả các đối tượng thu được bằng cách yêu cầu lấy chỉ để sở hữu có thể được sử dụng như là con đường phần.
Bạn nên xác định thuộc tính bền vững hơn của year và sử dụng nó làm sectionNameKeyPath.
thiết bạn FRC sectionNameKeyPath để year như vậy:

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

để hiển thị tên phần như một tiêu đề trong bảng, thực hiện:

- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section 
{ 
    id<NSFetchedResultsSectionInfo> sec = [self.fetchedResultsController sections][section]; 
    return [sec name]; 
} 
Các vấn đề liên quan