界面生成器中的 NSWindowController 对象链接

发布于 2024-11-10 09:07:32 字数 1463 浏览 4 评论 0原文

我创建了一个 NSWindow xib 文件,我想通过单击另一个窗口中的按钮来打开该文件。

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

同样我还创建了一个NSViewController的子类(即ListingViewController)来管理NSWindow内的NSView。为此,我将 NSViewController 从 xib 的 Library 中拖出,并将其类更改为 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 中为即将到来的窗口的视图控制器完成了所有绑定/view,即使在新窗口加载后(下面的代码),窗口和listingVC也会显示为(null),(null)。

- (void)windowDidLoad {
    [super windowDidLoad];

NSLog(@"windowDidLoad = %@, %@", self.window, self.listingVC);
}

请帮助解释为什么连接不起作用。我已经为这个问题绞尽脑汁有一段时间了。

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

蒂亚..

I created a NSWindow xib file that I want to open on click of a button in another window.

Now, to control the behavior of the NSWindow, I dragged an object from Library in xib and changed it to subclass of NSWindowController (i.e. ListingWindowController) that I defined in XCode.

Similarly I also created a subclass of NSViewController (i.e. ListingViewController) to manage the NSView inside the NSWindow. To do this, I dragged NSViewController from Library in xib and changed its class to ListingViewController.

@class ListingViewController;

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

@property (nonatomic, retain) IBOutlet ListingViewController *listingVC;
@end

I connected window and listingVC of my window controller in IB.

Now to invoke this window on click of a button in my launch (first) window, I create the window controller using initWithWindowNibName like this..

- (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];
    }
}

The problem is that despite all the bindings done in IB for the view controllers of upcoming window/view, the window and listingVC comes out to be (null), (null) even after the new window has loaded (below code).

- (void)windowDidLoad {
    [super windowDidLoad];

NSLog(@"windowDidLoad = %@, %@", self.window, self.listingVC);
}

Please help why the connections are not working. I'm banging my head against this problem for quite a while now.

PS: I'm coming from iOS programming background. So, I'm assuming the Mac's window/view controller behave similar to iOS UIViewControllers.

TIA..

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

野生奥特曼 2024-11-17 09:07:32

请注意:

wc = [[ListingWindowController alloc] initWithWindowNibName:@"ListingWindow" owner:self];

意味着 self (从你的问题中不清楚 self 是什么)是 ListingWindow.nib 的所有者。这意味着 self 是保留该 nib 文件中对象的出口的人,而 self 负责释放 nib 文件中的顶级对象。这也意味着您将在代码中创建 ListingWindowController 实例,并在 nib 文件中创建另一个实例,因为您已拖动 ListingWindowController< 类的对象/code> 到 nib 文件上。

这不应该是这样的。

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

为了为您的窗口控制器实现此目的,您需要将文件的所有者类设置为 ListingWindowController。您不得拖动对象立方体并在 nib 文件内实例化窗口控制器。窗口控制器是nib文件的所有者,因此它必须在nib文件加载之前存在。您还必须将文件所有者中的 window 出口链接到 nib 文件中的顶级窗口对象,以便窗口控制器知道它应该管理哪个窗口。

完成此操作后,请使用:

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

而不是:,

wc = [[ListingWindowController alloc] initWithWindowNibName:@"ListingWindow" owner:self];

因为 wc 应该是 nib 文件的所有者。

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

从您的问题中不清楚您是否有一个单独的 nib 文件用于视图。如果不这样做,那么根本不需要使用 NSViewController 的子类 - 您可以使用 NSObject 的子类来代替。如果您坚持使用 NSViewController 来管理不是从单独的 nib 文件加载的视图,那么您应该重写 -loadView ,以便某些人获得对该视图的引用意味着除了从 nib 文件加载它并发送 -setView: 以便它知道它应该管理的视图之外。

推荐阅读:资源编程指南中的 Nib 文件, NSWindowController类参考NSViewController 类参考

Note that:

wc = [[ListingWindowController alloc] initWithWindowNibName:@"ListingWindow" owner:self];

means that self (it’s not clear what self is from your question) is the owner of ListingWindow.nib. This means that self is the one who keeps outlets to objects in that nib file, and self is responsible for releasing the top-level objects in the nib file. This also means that you’re creating an instance of ListingWindowController in your code and another instance inside your nib file since you’ve dragged an object of class ListingWindowController onto the nib file.

This is not how it’s supposed to be.

In the vast majority of cases, a window (view) controller loads a nib file and becomes its owner. It has a window (view) outlet that must be linked to a top-level window (view) in the nib file. Being the nib file’s owner, it must have been created before the nib file is loaded.

In order to achieve this for your window controller, you need to set the file’s owner class to ListingWindowController. You must not drag an object cube and instantiate the window controller inside the nib file. The window controller is the owner of the nib file, so it must exist before the nib file is loaded. You must also link the window outlet in file’s owner to the top-level window object in the nib file so that the window controller is aware of what window it should manage.

Having done that, use:

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

instead of:

wc = [[ListingWindowController alloc] initWithWindowNibName:@"ListingWindow" owner:self];

since wc is supposed to be the owner of the nib file.

View controllers work similarly. They’re created before loading the nib file, are responsible for loading a nib file that contains a view as a top-level object, are that nib file’s owner, and have a view outlet that must be linked to that top-level view.

It’s not clear from your question whether you have a separate nib file for the view. If you don’t, then using a subclass of NSViewController is not needed at all — you could use a subclass of NSObject instead. If you insist on using NSViewController to manage a view that’s not loaded from a separate nib file, then you should override -loadView so that you get a reference to the view by some means other than loading it from a nib file, and sending it -setView: so that it is aware of the view it’s supposed to be managing.

Recommended reading: Nib Files in the Resource Programming Guide, NSWindowController class reference, NSViewController class reference.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文