我想知道的是我如何初始化窗口控制器
NSWindowController *c=[[NSWindowController alloc] initWithWindowNibName:@"Win" owner:myObj]
知道如果myObj不是控制器本身,它应该在Win.xib文件中控制哪个窗口?通常我将窗口控制器设置为所有者,以便我可以在IB上设置其窗口控制器。内存管理是否由窗口控制器完成,即使它不是所有者?
窗口控制器将对顶级对象进行内存管理,即使它不是所有者。来自NSWindowController
class reference:
无论谁是文件的所有者,窗口控制器都负责释放它加载的nib文件中的所有顶级对象。
窗口控制器通常是NIB的所有者,并且连接其窗口通常是它如何知道要控制哪个窗口。也可以使用-setWindow:
方法明确设置它。
可以想象,NSWindowController
搜索NIB的顶级对象以获得一个窗口来控制插座是否没有连接,但我不认为这样做。
你有没有发现一些你不理解的行为?它以前如何?
此方法适用于您拥有基于文档的应用程序的情况;见NSDocument
。在这种情况下,你将NSDocument
的一个实例作为NIB文件的所有者(NSDocument
有一个-setWindow:
方法,但没有getter for it)。控制器仍然会从文档实例中了解其窗口。代码大致是:
NSDocument * document = ...;
NSWindowController * winCtrl = [[NSWindowController alloc]
initWithWindowNibName:@"SomeNib" owner:document];
[document addWindowController:winCtrl];
[winCtrl loadWindow];
现在,文档是NIB文件的所有者,但窗口控制器仍然接收对分配给文档的窗口的引用。
当然这个代码仅用于演示目的,正确的方法实际上是子类NSDocument
,覆盖makeWindowControllers
,并在那里启动所有必需的控制器。
如果您的文档始终只有一个NIB文件中的单个窗口,您也可以将NSDocument
属性windowNibName
设置为NIB文件的名称,然后调用默认的makeWindowControllers
实现,该实现大致执行以下操作:
NSWindowController * winCtrl = [[NSWindowController alloc]
initWithWindowNibName:self.windowNibName owner:self];
[self addWindowController:winCtrl];
另请查看NSWindowController
的GNUStep实现,它可能与Apple的实现不同(Apple中的那个不是开源的,所以我们无法知道)但它的行为应该是相同的:
- (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);
}
}
}
资料来源:https://github.com/gnustep/libs-gui/blob/master/Source/NSWindowController.m
它将使用私有方法_transferWindowOwnership
从其文档中获取窗口,但只有在加载后没有设置窗口时,才会设置文档并且此文档已设置为加载的NIB文件的所有者。