NSArrayController,以编程方式创建CoreData实体,并且KVO

问题描述 投票:2回答:2

我有一个NSTableView,其NSTableColumn的值绑定到NSArrayController。 arrayController在我的核心数据管理对象上下文中控制一组实体。

效果很好,当通过UI Actions将新实体插入到arrayController中时,tableView将选择新项。

但是我将以编程方式在moc中创建新实体,然后在arrayController中选择新对象。

我尝试了以下操作:

Image *newImage = [Image newImage]; // convenience method to insert new entity into mod.
newImage.title = [[pathToImage lastPathComponent] stringByDeletingPathExtension];
newImage.filename = [pathToImage lastPathComponent];

[self.primaryWindowController showImage:newImage];

showImage:方法就是这样:

- (void)showImage:(Image *)image
{
    [self.imagesArrayController fetch:self];
    [self.imagesArrayController setSelectedObjects:@[image]];
}

但是,arrayController不会更改其选择。

我做错了吗?我假设我在moc中创建的newImage对象与arrayController正在控制的对象相同。如果是这样,为什么arrayController不更改其选择?

嗯-测试这个假设,我现在在运行时检查了arrayController的内容。新图像不存在-我认为这意味着我已经通过手动插入到Moc中而在绑定的“后面”了...

我的newImage便捷方法是这样:

+ (Image *)newImage
{
    Image *newImage = [NSEntityDescription insertNewObjectForEntityForName:@"Image" inManagedObjectContext:[[CoreDataController sharedController] managedObjectContext]];
    return newImage;
}

不符合KVO吗?

hmmm-编辑2 ...

我假定它是KVO兼容的,因为新图像出现在UI中。我现在正在考虑将实体插入到Moc和要通知的arrayController之间有一个延迟。

我从问题New Core Data object doesn't show up in NSArrayController arrangedObjects中看到(由SO很好地显示在该问题的右边),要求arrayController提取:应该有助于更新arrayController,但实际的提取:直到下次运行循环。

我应该使用计时器延迟对新对象的选择吗?似乎有点不雅...

cocoa core-data cocoa-bindings key-value-observing
2个回答
2
投票

对,好了,感谢这个问题:New Core Data object doesn't show up in NSArrayController arrangedObjects

我必须在插入新对象后立即在Moc上调用processPendingChanges:。

所以,现在我的新创建便捷方法是:

+ (Image *)newImage
{
    Image *newImage = [NSEntityDescription insertNewObjectForEntityForName:@"Image" inManagedObjectContext:[[CoreDataController sharedController] managedObjectContext]];
    [[[CoreDataController sharedController] managedObjectContext] processPendingChanges];
    return newImage;
}

0
投票

如果您要以编程方式执行此操作,最简单的方法就是将新实体对象直接添加到NSArrayController中,就像这样简单:

[self.imagesArrayController addObject:newImage];

这将把对象添加到控制器,然后选择它。

尽管有一个小故障-我不知道您用来显示NSArrayController内容的视图(NSView,UIView)-但NSTableView不会自动滚动以显示新添加的项目。

我不得不推迟这个(因为添加发生在以后的运行循环中),如下所示:

    NSUndoManager *um = self.managedObjectContext.undoManager;
[um beginUndoGrouping];
[um setActionName:NSLocalizedString(@"New Sample", NULL)];
PMWaterSample *sampleToAdd = [self createNewSample];
[self.samplesController addObject:sampleToAdd];

// Actual addition is deferred, hence we delay the scrolling too, on the main-thread's queue.
dispatch_async(dispatch_get_main_queue(), ^{
    [self.samplesController rearrangeObjects];

    // bring last row (newly added) into view
    NSUInteger selectedIdx = [self.samplesController selectionIndex];
    if (selectedIdx != NSNotFound) {
        [self.samplesTable scrollRowToVisible:selectedIdx];
    }
    [um endUndoGrouping];
});

希望这会有所帮助。我从来没有强迫MOC处理PendingChanges。我仍然感到有更好的方法可以执行此操作,并且让数组控制器使其嵌入UI元素滚动并显示新项,但我不知道如何。

© www.soinside.com 2019 - 2024. All rights reserved.