0

我正在尝试为我的 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 调用之后的第一个 fetch 请求(以及在我保存之前的所有进一步请求)会导致未排序的数据?

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
4

1 回答 1

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

于 2013-07-19T14:13:20.270 回答