如何通过 NSArrayController 从 Core Data 填充 NSTableView?

Posted

技术标签:

【中文标题】如何通过 NSArrayController 从 Core Data 填充 NSTableView?【英文标题】:How can I populate an NSTableView from Core Data via an NSArrayController? 【发布时间】:2012-08-28 06:09:21 【问题描述】:

最初我是通过一个插座填充我的 NSTableView 并将表的 dataSource 设置为我的控制器类。我正在尝试切换到使用 NSArrayController,以便我可以在我的应用程序中启用按列排序。

在 IB 中,我添加了一个数组控制器对象。我将排序描述符绑定连接到共享用户默认控制器,以便可以在我的应用程序启动之间保留排序的列。我将表的每一列都绑定到数组控制器,控制器键设置为“arrangedObjects”,模型键路径设置为应呈现的字段名称。

我的数据来自 Core Data,我尝试显示的实体与另一个实体有关系。第二个实体上的属性需要显示为表列之一的值。有人对我在这里缺少的东西有什么想法/建议吗?

MainWindowController.h

#import <Cocoa/Cocoa.h>
#import "Notification.h"

@class AppDelegate;

@interface MainWindowController : NSWindowController <NSTableViewDataSource, NSTableViewDelegate> 
    AppDelegate <NSApplicationDelegate> *appDelegate;


//@property NSMutableArray *userNotifications;

@property (weak) IBOutlet NSTableView *notificationsTable;
@property (weak) IBOutlet NSArrayController *notificationsController;

@end

MainWindowController.m

#import "AppDelegate.h"
#import "MainWindowController.h"
#import "Utils.h"

@implementation MainWindowController

//@synthesize userNotifications;

@synthesize notificationsTable;
@synthesize notificationsController;

- (void) doubleClick:(id)sender

    NSInteger row = [notificationsTable clickedRow];

//  Notification *clickedNotification = [userNotifications objectAtIndex:row];
//  Notification *clickedNotification = 

//  [appDelegate redirectToBrowser:clickedNotification];


- (id) initWithWindowNibName:(NSString *)windowNibName

    self = [super initWithWindowNibName:windowNibName];
    if (self) 
//      userNotifications = [[NSMutableArray alloc] init];
        appDelegate = (AppDelegate *) [[NSApplication sharedApplication] delegate];
        [notificationsController setManagedObjectContext:[appDelegate managedObjectContext]];
        [notificationsController setEntityName:@"Notification"];
        [notificationsController setAutomaticallyPreparesContent:YES];

        [notificationsController fetch:self];
        [notificationsTable reloadData];
    
    return self;


- (void)windowDidLoad

    [super windowDidLoad];

    // Implement this method to handle any initialization after your window controller's window has been loaded from its nib file.

    [notificationsTable reloadData];


- (void)awakeFromNib

    [notificationsTable setTarget:self];
    [notificationsTable setDoubleAction:@selector(doubleClick:)];

【问题讨论】:

【参考方案1】:

这个问题有两种解决方案:

    通过添加新对象并将类设置为 AppDelegate,将 App Delegate 对象添加到 IB。 通过将以下代码添加到您的 .h 和 .m 文件中,将 App Delegate 分配为控制器的实例变量 appDelegate

控制器.h

@class AppDelegate;

@interface Controller : NSWindowController 
    AppDelegate <NSApplicationDelegate> *appDelegate;

控制器.m

#import "AppDelegate.h"

- (id) initWithWindowNibName:(NSString *)windowNibName

    self = [super initWithWindowNibName:windowNibName];
    if (self) 
        appDelegate = (AppDelegate *) [[NSApplication sharedApplication] delegate];
    
    return self;

在任何一种情况下,您都需要为数组控制器添加一个新绑定。导航到 Inspector 中的 Binding 窗格并将 Managed Object Context(在 Parameters 下)设置为 Bind to (1) App Delegate 或 (2) File's Owner,然后将 Model Key Path 设置为 (1) self.managedObjectContext 或 ( 2) self.appDelegate.managedObjectContext

【讨论】:

以上是关于如何通过 NSArrayController 从 Core Data 填充 NSTableView?的主要内容,如果未能解决你的问题,请参考以下文章

NSArrayController 如何对一对多关系进行排序?

观察 NSArrayController 变化:检测插入或删除

如何将 NSArrayController 的内容集绑定到多个 NSArrayController 选择?

NSArrayController 没有拾取从另一个上下文合并的数据

从 CoreData 中删除所有对象后 NSArrayController 一直为空

如何使用 NSArraycontroller 在可可上创建 NSFetchedresultController?