Cocoa Interface builder中的NSWindowController对象链接

Cocoa Interface builder中的NSWindowController对象链接,cocoa,binding,interface-builder,nswindowcontroller,nsviewcontroller,Cocoa,Binding,Interface Builder,Nswindowcontroller,Nsviewcontroller,我创建了一个NSWindow xib文件,我想在另一个窗口中单击按钮打开该文件 现在,为了控制NSWindow的行为,我从xib中的库中拖动了一个对象,并将其更改为我在XCode中定义的NSWindowController(即ListingWindowController)的子类 类似地,我还创建了NSViewController的子类(即ListingViewController)来管理NSWindow中的NSView。为此,我从xib中的库中拖动了NSViewController,并将其类更

我创建了一个NSWindow xib文件,我想在另一个窗口中单击按钮打开该文件

现在,为了控制NSWindow的行为,我从xib中的库中拖动了一个对象,并将其更改为我在XCode中定义的NSWindowController(即ListingWindowController)的子类

类似地,我还创建了NSViewController的子类(即ListingViewController)来管理NSWindow中的NSView。为此,我从xib中的库中拖动了NSViewController,并将其类更改为ListingViewController

@class ListingViewController;

@interface ListingWindowController : NSWindowController {
    IBOutlet ListingViewController *listingVC;
}

@property (nonatomic, retain) IBOutlet ListingViewController *listingVC;
@end
我在IB中连接了窗口和窗口控制器的listingVC

现在,要在我的启动(第一个)窗口中单击按钮调用此窗口,我使用initWithWindowNibName创建窗口控制器,如下所示

- (IBAction) pushConnect:(id)sender {
    NSLog(@"Connect pushed.");
    if (wc == nil) {
        wc = [[ListingWindowController alloc] initWithWindowNibName:@"ListingWindow" owner:self];
        [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(closeWindow:) name:NSWindowWillCloseNotification object:nil];

        [wc showWindow:sender];
    }
}
问题在于,尽管在IB中为即将到来的窗口/视图的视图控制器进行了所有绑定,但即使在加载新窗口(代码下方)之后,窗口和列表VC仍然是(null),(null)。

- (void)windowDidLoad {
    [super windowDidLoad];

NSLog(@"windowDidLoad = %@, %@", self.window, self.listingVC);
}
请说明连接不工作的原因。我一直在为这个问题绞尽脑汁

PS:我来自iOS编程背景。因此,我假设Mac的窗口/视图控制器的行为类似于iOS UIViewController

TIA.

注意:

wc = [[ListingWindowController alloc] initWithWindowNibName:@"ListingWindow" owner:self];
表示
self
(您的问题中不清楚
self
是什么)是
ListingWindow.nib
的所有者。这意味着
self
负责将出口保存到该nib文件中的对象,而
self
负责释放nib文件中的顶级对象。这也意味着您正在代码中创建一个
ListingWindowController
实例,在nib文件中创建另一个实例,因为您已将类
ListingWindowController
的对象拖到nib文件中

事情不是这样的

在绝大多数情况下,窗口(视图)控制器加载nib文件并成为其所有者。它有一个
窗口
视图
)出口,必须链接到nib文件中的顶级窗口(视图)。作为nib文件的所有者,它必须在加载nib文件之前创建

要为窗口控制器实现这一点,需要将文件的所有者类设置为
ListingWindowController
不能拖动对象多维数据集并在nib文件中实例化窗口控制器。窗口控制器是nib文件的所有者,因此在加载nib文件之前它必须存在。您还必须将文件所有者中的
窗口
出口链接到nib文件中的顶级窗口对象,以便窗口控制器知道应该管理哪个窗口

完成后,请使用:

wc = [[ListingWindowController alloc] initWithWindowNibName:@"ListingWindow"];
而不是:

wc = [[ListingWindowController alloc] initWithWindowNibName:@"ListingWindow" owner:self];
因为
wc
应该是nib文件的所有者

视图控制器的工作原理类似。它们是在加载nib文件之前创建的,负责加载包含作为顶级对象的视图的nib文件,是该nib文件的所有者,并且具有必须链接到该顶级视图的
视图
出口

从您的问题中不清楚是否有单独的nib文件用于视图。如果不需要,则根本不需要使用
NSViewController
的子类-您可以使用
NSObject
的子类。如果您坚持使用
NSViewController
管理未从单独的nib文件加载的视图,则应覆盖
-loadView
,以便通过某种方式(而不是从nib文件加载)获取对视图的引用,并发送它
-setView:
,以便它知道应该管理的视图

建议阅读: