未保存的managedObjectContext中未排序的NSFetchRequest

时间:2013-07-18 19:49:32

标签: cocoa core-data nsfetchrequest

我正在尝试为我的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

1 个答案:

答案 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