在NSDocument体系结构中打开文档之前进行验证

时间:2009-08-18 13:56:20

标签: objective-c cocoa nsdocument

我有一个基于文档的应用程序,它格式化XML文件。

在我的NSDocument子类

中完成文档的编写和读取
- (BOOL)writeToURL:(NSURL *)absoluteURL ofType:(NSString *)typeName error:(NSError **)outError
- (BOOL)readFromURL:(NSURL *)absoluteURL ofType:(NSString *)typeName error:(NSError **)outError

但如果文件是无效的XML,我的应用程序就会崩溃。

所以我实施了:

- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename  
{  
  if(safe){open new document using .....makeDocumentWithContentsOfURL:......}  
   else{present alert}  
}

但是这有很多明显的副作用。我必须覆盖其他几种方法:

-(BOOL)writeSafelyToURL:(NSURL *)absoluteURL ofType:(NSString *)typeName     forSaveOperation:(NSSaveOperationType)saveOperation error:(NSError **)outError  
{  
    return [self writeToURL:absoluteURL ofType:typeName error:outError];  
    //return YES;  
}  

这就是沙滩球光标出现的地方,最终应用程序变得没有响应。

有没有更好的方法在打开之前验证文档?

3 个答案:

答案 0 :(得分:2)

您应该实现-readFromURL:ofType:error:,以免在错误的XML上崩溃。这是您应该进行验证的例程。代码的哪一部分导致崩溃,以及它是什么类型的崩溃?

关于-writeSafelyToURL:ofType:forSaveOperation:error:中的沙滩球,你可能会创造一个无限循环。 -writeToURL:ofType:error:可能会调用-writeSafelyToURL:....。无论如何,这是一种非常奇怪的超载方式。你想在这里实现什么?我不明白重载-application:openFile:与你的第一个问题或你描述的重载有什么关系。

答案 1 :(得分:1)

最好的办法是在你的应用程序中调用它:openFile:method:

[[NSDocumentController sharedDocumentController] openDocumentWithContentsOfURL:[NSURL fileURLWithPath:filename] display:YES error:&error];

使用它我没有任何问题(我也是文档架构的新手)。只需在该行之前进行验证,一切都应该有效。

您可能会觉得有用的另一件事:如果您覆盖任何针对不同类型的NSDocument加载/保存方法,请确保如果您不在其中执行保存/加载,则最后调用每个类型的超级版本。例如,对于一种类型的数据,您可以readFromData:ofType:error:,而对另一种数据可以readFromFileWrapper:ofType:error:,只要您在每次数据结束时调用[super ...],两者都会自动生效处理请求的类型。

答案 2 :(得分:0)

为什么不简单地使用返回代码 ??

直接来自readFromURL:ofType:error:的文档:

返回值
如果可以阅读文件内容,则是;否则,否。