Interface builder中的NSWindowController对象链接
Posted
技术标签:
【中文标题】Interface builder中的NSWindowController对象链接【英文标题】:NSWindowController object linkage in Interface builder 【发布时间】:2011-05-29 20:51:53 【问题描述】:我创建了一个 NSWindow xib 文件,我想在单击另一个窗口中的按钮时打开它。
现在,为了控制 NSWindow 的行为,我从 xib 中的 Library 中拖出一个对象,并将其更改为我在 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 中为即将到来的窗口/视图的视图控制器完成了所有绑定,但即使在新窗口加载后,窗口和 ListingVC 仍然是 (null), (null) (下面的代码)。
- (void)windowDidLoad
[super windowDidLoad];
NSLog(@"windowDidLoad = %@, %@", self.window, self.listingVC);
请帮助说明连接不工作的原因。我一直在努力解决这个问题。
PS:我来自 ios 编程背景。所以,我假设 Mac 的窗口/视图控制器的行为类似于 iOS UIViewControllers。
TIA..
【问题讨论】:
【参考方案1】:注意:
wc = [[ListingWindowController alloc] initWithWindowNibName:@"ListingWindow" owner:self];
表示self
(您的问题不清楚self
是什么)是ListingWindow.nib
的所有者。这意味着self
是保持该nib 文件中对象的出口的人,而self
负责释放nib 文件中的***对象。这也意味着您正在代码中创建 ListingWindowController
的实例,并在 nib 文件中创建另一个实例,因为您已将 ListingWindowController
类的对象拖到 nib 文件中。 p>
这不是应该的样子。
在绝大多数情况下,窗口(视图)控制器会加载一个 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 Files in the Resource Programming Guide、NSWindowController class reference、NSViewController class reference。
【讨论】:
以上是关于Interface builder中的NSWindowController对象链接的主要内容,如果未能解决你的问题,请参考以下文章
了解 Interface Builder 中的 Outlets
Interface Builder中的UIScrollView不滚动