我想爲我的Cocoa NSTableView實現一個控制器,它充滿了SQLite數據庫文件的數據。控制器實現了NSTableViewDataSource協議並且因此方法unsorted NSFetchRequest未保存的managedObjectContext
-(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)如何避免這種行爲而不保存(因爲我不能沒有輸入的必填字段)?
因爲我是新來的這整個可可和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
你不使用你的讀取請求任何類型的描述符。如果你這樣做,結果的排序不保證。我很驚訝它甚至是遠程一致的。 –
非常感謝湯姆,你是完全正確的。不知道我怎麼會錯過。 – Richard