我有一个基于文档的应用程序,它格式化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;
}
这就是沙滩球光标出现的地方,最终应用程序变得没有响应。
有没有更好的方法在打开之前验证文档?
答案 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:
的文档:
返回值
如果可以阅读文件内容,则是;否则,否。