2013-07-18 65 views
0

我想爲我的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 
+1

你不使用你的讀取請求任何類型的描述符。如果你這樣做,結果的排序不保證。我很驚訝它甚至是遠程一致的。 –

+0

非常感謝湯姆,你是完全正確的。不知道我怎麼會錯過。 – Richard

回答

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