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

问题描述 投票:4回答:2

我想知道的是我如何初始化窗口控制器

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

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

cocoa xib nswindow nib nswindowcontroller
2个回答
1
投票

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

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

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

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

你有没有发现一些你不理解的行为?它以前如何?


0
投票

此方法适用于您拥有基于文档的应用程序的情况;见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文件的所有者。

© www.soinside.com 2019 - 2024. All rights reserved.