【发布时间】:2011-02-23 22:03:02
【问题描述】:
我和我的团队一直在开发一个现有的、非基于文档的 Cocoa 应用程序。这是我们的第一个 Cocoa 应用程序,尽管到目前为止我们已经完成了许多 iOS 应用程序。
不过,该应用确实应该是基于文档的,所以我开始尝试对其进行转换。但是这里和那里的事情似乎没有奏效。例如,文件 -> 打开菜单项被永久禁用(尽管我最终启用了文件 -> 保存菜单项;最初它不会启用)。另外,我可以点击红色的 X 来关闭一个窗口,虽然 File -> Close 菜单项本身是禁用的;但是,当我通过 X 按钮关闭窗口时,不会调用我的 NSDocument 实现 (SPDocumentInfo) 中的 dealloc 方法。我创建了一个示例、全新的基于文档的应用程序,仅用于比较;当我在那里关闭一个窗口时,确实调用了 SPDocument 实现的 dealloc 方法(正如我所期望的那样。)所以这让我很担心。
我在这里和那里对项目进行了很多更改;它们包括:
-
使 SPDocumentInfo 在 .h 文件中像这样扩展 SPDocument:
@interface SPDocumentInfo : NSDocument <NSWindowDelegate> -
在 SPDocumentInfo 中实现了以下内容:
- (NSString *)windowNibName { return @"SPDocument"; } - (void)windowControllerDidLoadNib:(NSWindowController *) aController { [super windowControllerDidLoadNib:aController]; } - (NSData *)dataOfType:(NSString *)typeName error:(NSError **)outError { NSString *xml = [self toXml]; return [xml dataUsingEncoding:NSUTF8StringEncoding]; } - (BOOL)readFromData:(NSData *)data ofType:(NSString *)typeName error:(NSError **)outError { // will make this work later if ( outError != NULL ) { *outError = [NSError errorWithDomain:NSOSStatusErrorDomain code:unimpErr userInfo:NULL]; } return YES; } 编辑 .plist 文件以添加“文档类型”。除其他外,定义了“Cocoa NSDocument Class”=“SPDocumentInfo”。
更改了 SPDocumentInfo 中的一些连接以匹配基于文档的示例应用程序中的连接。例如,在 SPDocument.nib 中,文件的所有者(代表 SPDocumentInfo)是窗口的委托。
所以,我想知道在转换为基于文档的应用程序时是否还缺少其他类型的东西。或者,有没有关于如何做到这一点的指南? (我看过但找不到)。或者我应该从一个新的基于文档的应用程序重新开始,然后尝试将我们所有的东西都改造成它?一般来说,有没有人有这方面的经验?
【问题讨论】:
-
快速更新,以防有人关注。我之前意识到,我们在将一些菜单项连接到我们创建的特定网点时有些麻烦,而不是让它们保持指向默认的 First Responder 网点。一旦我恢复了默认连接,菜单项就会启用。至于 dealloc 方法没有按预期调用,我怀疑我们有一个循环依赖的问题,其中类包含对彼此的引用,因此永远不会达到零的保留计数(我猜,这是另一个话题)。所以我们也许可以解决
-
另一个更新:我不认为这个问题是循环依赖之一。我覆盖了我的 SPDocumentInfo 类和示例应用程序中的 MyDocument 类中的发布方法。当我在示例应用程序中关闭一个窗口时,释放由 [NSDocumentController removeObject] 和 [NSWindowController _windowDidClose] 调用(以及一些自动释放池弹出)。但是当我在我的应用程序中关闭窗口时,SPDocumentInfo 会发生 none 。所以不知何故,文档控制器和/或窗口控制器在我的应用程序中没有按预期运行。
标签: cocoa