我目前正在尝试自学 Cocoa 开发。为此,我购买了一本非常出色的书,Mac OS X 的 Cocoa Recipes: Vermont Recipes,其中介绍了如何创建示例应用程序。它非常好,但它是针对 XCode 3.2 而不是 XCode 4 编写的。到目前为止,我已经能够自己解决这个问题,但是我遇到了一个问题,我无法弄清楚如何按照说明进行操作。

从本质上讲,本书通过一个示例案例,对 NSDocumentController 进行子类化,以便应用程序可以处理两种(最终可能是任意数量的)不同类型的文档,并为每种类型打开相应的窗口。所以,我创建了一个 NSDocumentController 的自定义子类(书中称之为 VRDocumentController ),现在我需要让它在应用程序启动过程中相对较早地加载这个 Controller 的一个实例。基本上,这个类是一个单例,所以我必须在应用程序实例化标准类之前实例化我的类,这必须在过程的早期完成。很公平。

这本书引用了 Apple documentation for subclassing NSDocumentController ,它指出有两种方法可以解决问题:在 MainMenu.xib 文件中实例化类或在 -applicationWillFinishLaunching: 委托(delegate)方法中实例化一个。 Apple 文档没有给出关于如何执行其中任何一个的明确说明(稍后会详细介绍)并且该书仅涵盖第一个版本,我认为这可能是我的首选方法。

我的问题:我一生都无法在 XCode 4 中实现这一点。这本书为 XCode 3.2 提供的说明不再准确,因为 Interface Builder 现在已被改组到 XCode 本身和“类选项卡”的新版本不再显示我的项目的类(class)。我发现 this question on Stack Overflow 在问一个类似的问题,所以我尝试按照那里接受的答案进行操作。但是,当我打开 Identity Inspector 并尝试输入 VRDocumentController 时,它只是对我发出哔哔声而没有接受。我编写的其他 Controller 类似乎也不是可接受的输入。

我也很乐意走另一条路;在 -applicationWillFinishLaunching 方法中实例化一个副本。但是,我不知道该方法实际上属于哪个类,或者它的返回类型是什么。我也做了大量的搜索,但没有运气。

最佳答案

在您的应用程序委托(delegate)中:

// LukeAppDelegate.h
#import "LukeAppDelegate.h"
#import "VRDocumentController"

- (void)applicationWillFinishLaunching:(NSNotification *)notification {
    VRDocumentController *dc = [[VRDocumentController alloc] init];
}

这将确保 VRDocumentController 的实例被创建并注册为共享文档 Controller ,防止 Cocoa 使用默认的 NSDocumentController

至于为什么你不能在你的 nib 文件中使用自定义对象,请确保在将新对象拖入 nib 时选择对象(蓝色立方体)而不是对象 Controller (绿色球体内的蓝色立方体)文件。

编辑: 如果您的目标是支持恢复的 OS X 版本,则 -applicationWillFinishLaunching: 注册自定义文档 Controller 可能为时已晚。如果应用程序委托(delegate)放在 MainMenu.xib 中,它应该在任何文档恢复之前由 nib 加载过程实例化,因此您可以将 NSDocumentController 子类初始化移动到应用程序委托(delegate)的 init 方法:
// LukeAppDelegate.h
#import "LukeAppDelegate.h"
#import "VRDocumentController"

- (id)init {
    self = [super init];
    VRDocumentController *dc = [[VRDocumentController alloc] init];
    return self;
}

关于objective-c - 如何在 XCode 4 中使用 NSDocumentController 的子类?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/7373446/

10-13 04:00