4

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

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

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

4

2 回答 2

1

窗口控制器将执行顶级对象的内存管理,即使它不是所有者。从NSWindowController 类参考

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

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

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

你有没有观察到一些你不理解的行为?它以前如何?

于 2013-02-09T20:34:38.757 回答
0

此方法适用于您拥有基于文档的应用程序的情况;见NSDocument。在这种情况下,您将创建一个NSDocumentNIB 文件所有者的实例(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 文件的名称,然后调用默认makeWindowControllers实现,大致执行以下操作:

NSWindowController * winCtrl = [[NSWindowController alloc]
   initWithWindowNibName:self.windowNibName owner:self];
[self addWindowController:winCtrl];

还要检查 GNUStep 的实现NSWindowController,它可能与 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 文件的所有者。

于 2019-04-04T15:04:49.200 回答