[NSWindowController initWithWindowNibName:owner]中窗口控制器以外的所有者?

时间:2013-02-09 16:00:57

标签: cocoa xib nswindow nib nswindowcontroller

我想知道的是窗口控制器如何用

初始化
NSWindowController *c=[[NSWindowController alloc] initWithWindowNibName:@"Win" owner:myObj]

如果myObj不是控制器本身,知道它应该在Win.xib文件中控制哪个窗口?通常我将窗口控制器设置为所有者,以便我可以在IB上设置其窗口控制器。内存管理是否由窗口控制器完成,即使它不是所有者?

2 个答案:

答案 0 :(得分:1)

窗口控制器将对顶级对象进行内存管理,即使它不是所有者。来自NSWindowController class reference

  

无论文件的所有者是谁,窗口控制器都是   负责释放nib文件中的所有顶级对象   负荷。

窗口控制器通常是NIB的所有者,并且连接其窗口插座通常是它知道控制哪个窗口的方式。也可以使用-setWindow:方法明确设置它。

可以想象NSWindowController在NIB的顶级对象中搜索一个窗口来控制插座是否没有连接,但我不认为它会这样做。

您是否观察到一些您不理解的行为?它是什么?

答案 1 :(得分:0)

如果您有一个基于文档的应用程序,则此方法存在;参见NSDocument。在这种情况下,您将创建一个NSDocument实例的NIB文件的所有者(NSDocument有一个-setWindow:方法,但没有getter方法)。控制器仍将从文档实例中了解其窗口。代码大致为:

NSDocument * document = ...;
NSWindowController * winCtrl = [[NSWindowController alloc]
   initWithWindowNibName:@"SomeNib" owner:document];
[document addWindowController:winCtrl];
[winCtrl loadWindow];

现在该文档是NIB文件的所有者,但是窗口控制器仍然收到对分配给该文档的窗口的引用。

当然,此代码仅用于演示目的,正确的方法实际上是对NSDocument进行子类化,覆盖makeWindowControllers并在那里初始化所有必需的控制器。

如果您的文档始终始终只有一个NIB文件中的一个窗口,则也可以将NSDocument属性windowNibName设置为NIB文件的名称,然后调用默认的{{1 }}实现,大致执行以下操作:

makeWindowControllers

还要检查NSWindowController * winCtrl = [[NSWindowController alloc] initWithWindowNibName:self.windowNibName owner:self]; [self addWindowController:winCtrl]; 的GNUStep实现,它可能不同于Apple的GNUStep实现(Apple的不是开源的,所以我们不知道),但其行为应相同:< / p>

NSWindowController

来源:https://github.com/gnustep/libs-gui/blob/master/Source/NSWindowController.m

它将使用私有方法- (void) loadWindow { NSDictionary *table; if ([self isWindowLoaded]) { return; } table = [NSDictionary dictionaryWithObject: _owner forKey: NSNibOwner]; if ([NSBundle loadNibFile: [self windowNibPath] externalNameTable: table withZone: [_owner zone]]) { _wcFlags.nib_is_loaded = YES; if (_window == nil && _document != nil && _owner == _document) { [self setWindow: [_document _transferWindowOwnership]]; } else { // The window was already retained by the NIB loading. RELEASE(_window); } } else { if (_window_nib_name != nil) { NSLog (@"%@: could not load nib named %@.nib", [self class], _window_nib_name); } } } 从其文档中获取窗口,但只有在加载后未设置任何窗口,已设置文档且该文档已被设置为已加载NIB文件的所有者时,该窗口才会显示。