mso*_*ler 9 macos cocoa objective-c nsdocument
我正在研究我的第一个基于Mac文档的应用程序.
我已经进行了子类化NSDocument,重新实现了诸如的方法
- (BOOL)readFromURL:(NSURL *)absoluteURL ofType:(NSString *)typeName error:(NSError **)outError;
- (BOOL)writeToURL:(NSURL *)absoluteURL ofType:(NSString *)typeName error:(NSError **)outError;
- (void)makeWindowControllers;
Run Code Online (Sandbox Code Playgroud)
主窗口控制器是一个子类NSWindowsController,包含两个NSViewController子类.
我面临的问题是我需要从这些视图控制器访问当前文档.我所做的就是打电话
MyDocument *myDocument = [[NSDocumentController sharedController] currentDocument];
Run Code Online (Sandbox Code Playgroud)
首先,在启动应用程序后,立即创建一个新文档.然后,创建主窗口及其视图控制器,但上面的方法返回nil.这是我得到的日志(使用NSLog):
Just created this new document: <MyDocument: 0x10040ff10>
I'm in a view controller and current document is (null)
Run Code Online (Sandbox Code Playgroud)
之后,创建一个新文档并调用此方法会产生一个非零指针,但它不会指向正确的文档,而是指向第一个:
Just created this new document: <MyDocument: 0x100437e10>
I'm in a view controller and current document is <MyDocument: 0x10040ff10>
Run Code Online (Sandbox Code Playgroud)
请注意,在创建第二个文档后,currentDocument指向第一个文档而不是第二个文档.
知道我错过了什么或做错了吗?什么时候currentDocument设置NSDocumentController?
(我将离开之前的答案,因为它在被要求提供NSView的子类时回答了这个问题,但是现在原来的海报已经声明他正在使用NSViewController,有不同的考虑因素).
在NSViewController受控视图的情况下,NSViewController使用representedObject属性将其附加到其数据.这个抽象旨在由NSViewController包含的控制器管理,听起来就像是你的NSWindowController.
根据您希望/需要提供的封装量,您可以将文档推送到NSViewControllers(如果它们在整个文档上运行),或者只推送与特定NSViewController密切相关的文档中的信息.
例如,我将假设一个软件编辑有关火车的设计信息:引擎,汽车和守车.的NSDocument子类包含单个发动机对象,一个单一对象守车,和0个或更多的车对象.在这种情况下,您可能有3 NSView秒,每个都有自己的NSViewController处理来自对象的视图中的移动数据.
NSWindowController处理将每个NSViewController人设置representedObject为它理解的对象.例如,当视图完成加载时,窗口控制器将:
[engineViewController setRepresentedObject: engine];
[cabooseViewController setRepresentedObject: caboose];
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用NSTableView显示汽车列表,并且(当正在查看汽车时),窗口控制器可以[carViewController setRepresentedObject: car];在更改选择时使用(或者您可以使用绑定,具体取决于代码的结构) .
这样,您可以充分利用MVC范例,因为控制器会根据需要将视图链接到模型,但文档结构只能由顶级NSWindowController真正理解.
从苹果文档中NSDocumentController currentDocument可以看出:
如果在应用程序未激活时调用此方法,则返回 nil。这可能发生在处理拖放操作期间,例如,在 readSelectionFromPasteboard: 的实现中。在这种情况下,请从与文档关联的 NSView 子类发送以下消息:
[[[self window] windowController] document];
这有点模糊,因为它并没有真正限定“不活跃”的含义。拖放操作可能是唯一的触发器,但它没有说明这是否是应用程序变得不活动的唯一触发器。
也许苹果建议的替代方案对您有用。
| 归档时间: |
|
| 查看次数: |
2662 次 |
| 最近记录: |