【发布时间】:2017-03-18 13:04:35
【问题描述】:
我正在制作一个仅在菜单栏中运行的 macOS Cocoa 应用程序。当我最初创建项目时,Xcode 给了我一个名为MainMenu.xib 的文件。这个MainMenu.xib 文件似乎不包含与我的菜单栏应用程序相关的任何内容,因此我希望将其删除。
Cocoa 入口点the function NSApplicationMain,“从应用程序的主包中加载主 nib 文件”。我在其他地方读到 Cocoa 通过查询我的Info.plist 中的键NSMainNibFile 找到了“主笔尖文件”,该键设置为字符串MainMenu。我删除了密钥NSMainNibFile,我的程序仍然表现相同。由此,我假设 Cocoa 看到了这个键的缺失,所以它跳过了它的 nib/xib 加载步骤。
由于我的MainMenu.xib 文件不再从任何地方引用,我删除了它(这从我的project.pbxproj 中删除了一些看似无辜的引用)。但是,删除MainMenu.xib 后,我的应用程序不再工作。我的AppDelegate 类上的applicationDidFinishLaunching 方法没有被调用!
这意味着两件事。首先,这意味着即使NSMainNibFile 不存在,Cocoa 仍然会神奇地找到我的MainMenu.xib 文件(如果我将其重命名为Foo.xib,Cocoa 仍然会找到该文件)。更重要的是,这意味着我的MainMenu.xib is 中的某些内容仍然需要我的应用程序运行。这是完整的MainMenu.xib:
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="11762" systemVersion="16D32" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="11762"/>
</dependencies>
<objects>
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication">
<connections>
<outlet property="delegate" destination="Voe-Tx-rLC" id="GzC-gU-4Uq"/>
</connections>
</customObject>
<customObject id="-1" userLabel="First Responder" customClass="FirstResponder"/>
<customObject id="-3" userLabel="Application" customClass="NSObject"/>
<customObject id="Voe-Tx-rLC" customClass="AppDelegate" customModule="Foo" customModuleProvider="target"/>
</objects>
</document>
我认为问题在于我的MainMenu.xib 引用了我的AppDelegate 类,而Cocoa 使用它来实例化AppDelegate 类,然后在对象上调用applicationDidFinishLaunching。这令人困惑,因为我认为 AppDelegate 类上的 @NSApplicationMain 注释就足够了。
因此,我有几个问题:
-
Cocoa(即
NSApplicationMain)如何找到我的MainMenu.xib文件? Cocoa 的搜索程序是什么?如何让 Cocoa 跳过这个加载步骤? -
我的
MainMenu.xib文件在做什么? 也就是说,Cocoa 是如何解释MainMenu.xib文件的,结果它做了什么?具体来说,这个文件如何导致我的AppDelegate类被实例化? -
如何在 Swift 3 中纯粹以编程方式重新创建此逻辑,以便删除
MainMenu.xib文件?我需要使用哪些 API?
【问题讨论】:
-
其中一个问题stackoverflow.com/questions/5237833/…可能重复
-
另请注意developer.apple.com/reference/appkit/nsapplication,它描述了
NSApplicationMain的实际作用。 -
@Sulthan 谢谢,但不完全是:这个问题与拆分 .xib 文件有关,而我关心的是完全删除 .xib 文件。
-
恕我直言,nib 只做一件事 - 它创建一个委托实例并将其连接到
NSApp。 -
我很好奇……你为什么对摆脱 XIB 感兴趣?