在核心数据的应用程序更新一个NSTableView的正确方法(Correct way of upda

2019-07-17 12:24发布

我有一个NSTableView其中列绑定到一个NSArrayController核心数据项目。 反过来,控制器的内容被绑定到AppDelegate中的主管理对象上下文。

我子类NSTextFieldCell的提供显示数据的更加个性化的方式。 一切似乎运作良好,但是当我通过列举在上下文中的对象并更改属性,NSArrayController中似乎并没有通过表通过新的价值。 我知道他们正在被改变为sortDescriptors工作,该表根据新的数据,但同时仍显示旧值自我组织。 我猜这是向下的的NSCell的是显示的数据的回收:虽然基本价值已经在核心数据DB被改变他们不会重新绘制。

尝试各种KVO通知与后[myArrayController willChangeValueFor: aKeyPath]和相应的didChange以及简单[myTable reloadData] 我唯一的解决办法是解开managedObjectContext控制器的结合,并重新把它挂处理之后,像这样:

self.hasBackgroundOp = YES;
self.isCancelled = NO; //can get changed with a 'cancel' button in the UI
    if (self.managedObjectContext.hasChanges) {
        [self. managedObjectContext save:nil];
    }
    [myArrayController setManagedObjectContext:nil]; //brutal un-hooking of controller
    dispatch_group_t dispatchGroup = dispatch_group_create();
    dispatch_group_async(dispatchGroup, dispatch_get_global_queue(0, 0), ^{
        .
        .
        // create a thread context, set the persistent store co-ord
        // and do some processing on the
        // NSManagedObjects that are fetched into an array just
        // for the purpose of this thread
        .
        .
        [ctx save:&error];
        //and after the processing is finished then refresh the table
        dispatch_async(dispatch_get_main_queue(), ^{
            [myArrayController setManagedObjectContext:self.managedObjectContext]; //this forces re-drawing of the table
            self.hasBackgroundOp = NO;
            self.isCancelled = NO;
        });
    });

这似乎真的残酷的是做[myArrayController setManagedObjectContext:nil]; ,然后再设置它只是刷新表的内容。 我简直不敢相信,虽然它只是罚款我已经正确做到了这一点。 任何人都可以提出建议的更好的办法? 谢谢!

更新:在实际设置管理对象上下文并不能解决问题。 这似乎已经停止工作。 如果代码连续运行两次,然后应用程序只是挂起。 注释掉-setManagedObjectContext:线条,以及所需的代码可以运行多次。

在回应的意见,我的自定义单元格用来显示自己的情况如下:

NSInteger index = [[self stringValue] integerValue] + 1;
NSAttributedString *cellText = [[NSAttributedString alloc] initWithString:[NSString stringWithFormat:@"%lu",index] attributes:attributes];
NSRect textRect;
textRect.origin = cellFrame.origin;
textRect.origin.x += (cellFrame.size.width - cellText.size.width) / 2;
textRect.origin.y += (cellFrame.size.height - cellText.size.height) / 2;
textRect.size.width = cellText.size.width;
textRect.size.height = cellText.size.height;
[cellText drawInRect:textRect];

阵列控制器是在主笔尖设置和有它管理绑定到AppDelegate中的对象上下文。 有没有取在笔尖请求或谓语 - 一种描述,在AppDelegate代码约束:

[myArrayController setSortDescriptors:[NSArray arrayWithObject:[NSSortDescriptor sortDescriptorWithKey:kINDEX ascending:YES]]];

Answer 1:

我想我已经找到了它 - 我增加了以下的螺纹加工结束并执行它在主线程上:

[self.managedObjectContext reset];
[myArrayController fetch:self];

重置MOC显然将其清除,从而迫使控制器重绘细胞。 该-fetch似乎是必要的,否则表一片空白......



文章来源: Correct way of updating an NSTableView in a Core Data app