在 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;
}
这就是沙滩球光标出现的地方,最终应用程序变得无响应。
有没有更好的方法在打开之前验证文档?
I have an document based application which formats an XML file.
Writing and reading of document is done in my NSDocument subclass
- (BOOL)writeToURL:(NSURL *)absoluteURL ofType:(NSString *)typeName error:(NSError **)outError
- (BOOL)readFromURL:(NSURL *)absoluteURL ofType:(NSString *)typeName error:(NSError **)outError
but if the file is an invalid XML, my app is simply crashing.
So I implemented:
- (BOOL)application:(NSApplication *)theApplication openFile:(NSString *)filename
{
if(safe){open new document using .....makeDocumentWithContentsOfURL:......}
else{present alert}
}
But there are lot of apparent side effects with this. I have to override couple of other methods:
-(BOOL)writeSafelyToURL:(NSURL *)absoluteURL ofType:(NSString *)typeName forSaveOperation:(NSSaveOperationType)saveOperation error:(NSError **)outError
{
return [self writeToURL:absoluteURL ofType:typeName error:outError];
//return YES;
}
And this is where the beach-ball cursor appears and eventually the application becomes unresponsive.
Is there a better way to validate the document before opening?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您应该实现
-readFromURL:ofType:error:
,这样它就不会在错误的 XML 上崩溃。这是您应该进行验证的例程。代码的哪一部分导致了崩溃,以及它是什么类型的崩溃?关于
-writeSafelyToURL:ofType:forSaveOperation:error:
中的沙滩球,您可能正在创建一个无限循环。-writeToURL:ofType:error:
可能会调用-writeSafelyToURL:....
。无论如何,这是一种非常奇怪的超载方式。你想在这里实现什么目标?我不明白重载-application:openFile:
与您的第一个问题或您描述的重载有何关系。You should be implementing
-readFromURL:ofType:error:
such that it does not crash on bad XML. This is the routine that you should be doing your validation in. What part of your code is causing the crash, and what kind of crash is it?Regarding the beachball in
-writeSafelyToURL:ofType:forSaveOperation:error:
, you're probably creating an infinite loop. It is possible that-writeToURL:ofType:error:
calls-writeSafelyToURL:....
. In any case, this is a very strange way to overload it. What are you trying to achieve here? I don't understand how overloading-application:openFile:
is related to either your first problem or the overload you describe.最好的选择是在您的应用程序中调用此方法:openFile:方法:
使用它我没有遇到任何问题(我也是文档架构的新手)。只需在该行之前进行验证即可,一切都应该正常。
您可能会发现有用的另一件事:如果您重写任何不同类型的 NSDocument 加载/保存方法,如果您不在其中执行保存/加载,请务必在最后调用每个方法的超级版本。例如,您可以将
readFromData:ofType:error:
用于一种数据类型,而readFromFileWrapper:ofType:error:
用于另一种类型的数据,只要您这样做,两者都会自动工作如果您不处理请求的类型,请在每个末尾调用[super ...]
。The best bet is calling this in your application:openFile: method:
Using that I haven't had any issues (I'm new to the Document Architecture as well). Just do your validation before that line and everything should work.
Another thing you might find useful: if you override any of the NSDocument loading/saving methods for different types, be sure to call the super version of each at the end if you don't do the save/load within them. So for example you can have
readFromData:ofType:error:
for one type of data butreadFromFileWrapper:ofType:error:
for another, and both will automatically work as long as you call[super ...]
at the end of each if you don't handle the requested type.为什么不简单地使用返回代码?
直接来自
readFromURL:ofType:error:
的文档:返回值
是,如果可以读取文档内容;否则,不。
Why not simply use the return code??
Straight from the docs for
readFromURL:ofType:error:
:Return Value
YES if the document contents could be read; otherwise, NO.