我已经在项目中多次使用NSWindowController,感觉对这个重要类背后的概念有(非常)粗略的了解。我想对这篇文章做的是澄清/纠正我自己的理解,并希望帮助其他学习者迈出第一步。我发现一览表的概念,概述和最佳实践是最有用的,并且在文档中经常缺少。这是我对NSWindowController的看法(问题以粗体显示):

  • (概念上)在每个窗口笔尖下方都存在一个NSWindowController(NSWC)子类,它充当用户界面元素和它们控制/表示的模型对象之间的胶粘剂。基本上,应用程序中的每个窗口都应具有自己的NSWC子类。
  • 笔尖的文件所有者应始终为NSWC子类。 即使对于MainMenu.xib应用程序也是如此吗?
  • 应该始终将NSWC的window属性链接到InterfaceBuilder中的NSWindow。
  • 您应该使用[super initWithWindowNibName:]覆盖'init'方法,以便在引用[mycontroller window]时将加载笔尖。 即使在启动时已打开,对于MainMenu.xib窗口的NSWC是否也是如此?
  • NSWC不应做太多繁重的工作-它应该简单地将消息传递给对象实例,并在UI中呈现这些对象。
  • 它可以使用绑定(bind)来修改UI,或者充当表的委托(delegate)等,或者在观察到更改时通过主动更改UI元素或上述任何一项的组合(您使用的似乎是一个问题)口味,各有利弊)。
  • 如果需要,NSWC可以创建其他NSWC的实例(例如,打开一个一次性子窗口时)。
  • 使用[mycontroller showWindow:nil]在前面显示关联的窗口。如果您希望窗口显示为工作表,请使用以下方法:
    NSWindowController* mycontroller = [[MyController alloc] init];
    [NSApp beginSheet: [mycontroller window]
       modalForWindow: [self window]
        modalDelegate: self
       didEndSelector: @selector(didEndMySheet:returnCode:contextInfo:)
          contextInfo: nil];
    
  • didEndSelector:应该是父窗口的NSWC的方法,并且可以使用[sheet windowController]访问和释放“mycontroller”。
    -要关闭窗口,请调用NSWC窗口的performClose:方法。

    一些问题:
  • MainMenu窗口的NSWC是否也应为应用程序委托(delegate),或者应为其他类?
  • 同样,主要的NSWC应该处理文件(拖放/打开),还是应该将其传递给应用程序委托(delegate),还是只是出于口味?

  • 如果其中任何一种不好的做法,或者完全是错误的,请纠正我。我想澄清我对NSWindowController的理解,因此,任何补充(以最佳实践,经验和陷阱的形式)都将受到高度赞赏。

    谢谢,
    劳里

    最佳答案

    窗口 Controller 实际上是做什么用的?

    窗口 Controller 是从NIB文件加载窗口并管理NIB中分配的资源的内存的工具。在此之前NSWindowControllers基本上必须为每个窗口编写相同的代码或发明自己的窗口 Controller 类。

    当然,它们也是“模型/ View / Controller ”意义上的 Controller ,因此它们是将 View 从窗口连接到模型对象的正确位置。为此,它们通常需要充当 View 对象的委托(delegate)或数据源。因此,您完全可以正确理解这一部分。

    窗口 Controller 也是代码重用的工具。可以轻松地将窗口 Controller 类和它的XIB / NIB放到另一个项目中并在其中使用。

    因此,是的,除了一个异常(exception),NIB的每个窗口都应由窗口 Controller 拥有。实际上,这只是好的代码的准则,没有任何东西可以强制执行。

    WindowControllers和MainMenu.xib
    MainMenu.xib是另一回事,您无法使用窗口 Controller 。该NIB由NSApplication加载,因此必须是“文件所有者”。无法在NSApplication和NIB之间获得窗口 Controller 。也不必在该处使用窗口 Controller 进行内存管理,因为该应用程序对象在程序的整个运行时都存在,因此不必在释放NIB时从NIB中清除其资源。

    如果您确实需要主窗口的窗口 Controller ,则不能将其放在MainMenu.xib中。

    我希望这有帮助。关于窗口 Controller ,可能还有很多要说的

    10-04 13:38