我正在尝试为我的Cocoa NSTableView实现一个控制器,它充满了SQLite数据库文件的数据。控制器实现NSTableViewDataSource协议,因此实现方法
-(NSInteger)numberOfRowsInTableView:(NSTableView*)tableView {
}
和
-(id)tableView:(NSTableView*)tableView setObjectValue:(id)object
forTableColumn:(NSTableColumn*)tableColumn
row:(NSInteger*)row {
}
显然经常被称为安静(例如,如果我滚动表格)。为了向两个方法提供最新数据,每次调用其中一个方法时,我都在执行NSFetchRequest。
实际问题与我的IBAction有关,它为我的表添加了一个新条目。在这个方法的最后,我在表视图上调用reloadData方法,如果我是正确的,它至少调用两个协议方法,然后导致表中的未排序数据。我已经发现每个NSFetchRequest返回这个未排序的数据,直到我保存managedObjectContext。但这不是一个选项(甚至不可能),因为有一个必填字段,需要先在表格中填写。
所以这是我的两个问题:
1)为什么我在insertNewObjectForEntityForName调用之后的第一次获取请求(以及我保存之前的所有其他请求)都会导致未排序的数据?
2)如何在不保存的情况下避免这种行为(因为我不能没有输入的必填字段)?
由于我是新手Cocoa和CoreData的新手,我将发布完整的代码,让您清楚地了解我正在尝试做什么。欢迎提出任何意见。
此致
理查德
#import "EventTabController.h"
#import "CoreData.h"
#import "Season.h"
@implementation EventTabController
-(id) init {
if(self = [super init]) {
managedObjContext = [[CoreData getInstance] managedObjContext];
}
return self;
}
/**
* Part of the NSTableViewDataSource protocol. This method must return the number of
* elements that are currently to be shown in the table.
*/
-(NSInteger)numberOfRowsInTableView:(NSTableView *)tableView {
NSError *err;
NSInteger numOfRows = [managedObjContext countForFetchRequest:[self createSeasonFetchRequest] error:&err];
NSLog(@"[%@] %lu objects in table", [self class], (long)numOfRows);
return numOfRows;
}
/**
* Part of the NSTableViewDataSource protocol. This method must return the object for a specific cell,
* The cell is identified by a row number and a NSTableColumn object.
*/
-(id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
NSError * err;
NSArray* result = [managedObjContext executeFetchRequest:[self createSeasonFetchRequest] error:&err];
Season *season = [result objectAtIndex:row];
NSObject* obj = [season valueForKey:[tableColumn identifier]];
NSLog(@"[%@] Index: %lu - %@", [self class], (long)row, obj);
return obj;
}
/**
* Part of the NSTableViewDataSource protocol. This method sets the value for an entity, that was entered in the table.
* The value to insert is identified by a row number and a NSTableColumn object.
*/
- (void)tableView:(NSTableView *)tableView setObjectValue:(id)object forTableColumn:(NSTableColumn *)tableColumn row:(NSInteger)row {
NSError * err;
NSArray* result = [managedObjContext executeFetchRequest:[self createSeasonFetchRequest] error:&err];
Season *season = [result objectAtIndex:row];
[season setValue:object forKey:[tableColumn identifier]];
}
/**
* Creates a fetch request for the Season entity. The request does not include any subentities.
*/
-(NSFetchRequest*) createSeasonFetchRequest {
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:[NSEntityDescription entityForName:@"Season" inManagedObjectContext:managedObjContext]];
[fetchRequest setIncludesSubentities:NO];
return fetchRequest;
}
/**
* Called when the 'Add Season' button is pressed in the gui. It creates a new (empty) Season object
* within the managedObjectConext and forces the season table to refresh;
*/
- (IBAction)addSeason:(id)sender {
NSLog(@"[%@] 'Add Season' button has been pressed...", [self class]);
[NSEntityDescription insertNewObjectForEntityForName:@"Season" inManagedObjectContext:managedObjContext];
[seasonTable reloadData];
}
@end
答案 0 :(得分:0)
汤姆指出,我错过了添加NSSortDescriptor。
我修改了我的代码,它就像魅力一样。
/**
* Creates a fetch request for the Season entity. The request does not include any subentities.
*/
-(NSFetchRequest*) createSeasonFetchRequest {
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
[fetchRequest setEntity:[NSEntityDescription entityForName:@"Season" inManagedObjectContext:managedObjContext]];
[fetchRequest setIncludesSubentities:NO];
NSSortDescriptor *sortDescriptor = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
[fetchRequest setSortDescriptors:@[sortDescriptor]];
return fetchRequest;
}
我阅读本文是为了更清楚地了解如何使用基本的NSSort功能:Apple Developer - CoreData Fetching