以编程方式重命名 NSDocument 文件时防止出现警告
我的应用程序允许用户重命名当前打开的文档。这很简单,而且工作得很好,但有一个我无法弄清楚的非常烦人的错误。当文件被重命名时,AppKit(友善地)会在用户下次尝试保存文档时发出警告。用户说“确定”,一切都会正常进行。当应用程序外部的某些内容更改了文档时,这是有意义的,但当它实际上是由文档本身完成时,则没有意义。
代码是这样的:
-(void)renameDocumentTo:(NSString *)newName {
NSURL *newURL = [[[self fileURL] URLByDeletingLastPathComponent]
URLByAppendingPathComponent:newName];
NSFileManager *fileManager = [NSFileManager defaultManager];
[fileManager moveItemAtURL:[self fileURL] toURL:newURL];
NSDictionary *attrs = [fileManager attributesForItemAtPath:[newURL path] error:NULL];
[self setFileURL:newURL];
[self setFileModificationDate:[attrs fileModificationDate]];
}
人们可能认为在文档上明确设置新的 URL 和修改日期就足够了,但遗憾的是事实并非如此。 Cocoa 仍然会生成警告。
我尝试更改顺序(在文档上设置新 URL,然后重命名文件),但这没有帮助。
我还尝试了用户在 CocoaDev 的旧帖子上建议的修复:
[self performSelector:@selector(_resetMoveAndRenameSensing)];
但是,即使这样也不能停止警告,我猜必须是执行此操作的正确方法使用记录的 API。当用户单击项目树上的文件并将其重命名为其他名称时,Xcode 如何处理事情。它不会警告用户有关重命名的信息,因为用户实际上执行了重命名。
我需要做什么?
My application allows the user to rename documents that are currently open. This is trivial, and works fine, with one really annoying bug I can't figure out. When a file is renamed, AppKit (kindly) warns the user the next time they try to save the document. The user says "OK" and everything continues as normal. This makes sense when something external to the application changed the document, but not when it was actually done by the document itself.
The code goes something like this:
-(void)renameDocumentTo:(NSString *)newName {
NSURL *newURL = [[[self fileURL] URLByDeletingLastPathComponent]
URLByAppendingPathComponent:newName];
NSFileManager *fileManager = [NSFileManager defaultManager];
[fileManager moveItemAtURL:[self fileURL] toURL:newURL];
NSDictionary *attrs = [fileManager attributesForItemAtPath:[newURL path] error:NULL];
[self setFileURL:newURL];
[self setFileModificationDate:[attrs fileModificationDate]];
}
One would think that expressly setting the new URL and modification date on the document would be enough, but sadly it's not. Cocoa still generates the warning.
I've tried changing the order (setting the new URL on the document, THEN renaming the file) but this doesn't help.
I've also tried a fix suggested by a user on an old post over at CocoaDev:
[self performSelector:@selector(_resetMoveAndRenameSensing)];
Even this does not stop the warning however, and I'm guessing there has to be a proper way to do this using the documented API. How does Xcode handle things when a user clicks a file on the project tree and renames it to something else. It doesn't warn the user about the rename, since the user actually performed the rename.
What do I need to do?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
主要文档中对此没有太多内容。相反,请查看 10.5 发行说明:http:// /developer.apple.com/library/mac/#releasenotes/Cocoa/AppKitOlderNotes.html%23X10_5Notes 标题下的“NSDocument Checking for Modified Files At Saving Time”
(对于 Xcode,它具有悠久的历史)如果项目中的文件不使用
NSDocument
,我也不会感到惊讶)值得注意的是,移动文件不会更改其修改日期,因此调用
-setFileModificationDate:
不太可能产生任何影响。因此,一种可能性可能是绕过
NSDocument
的通常警告,如下所示:理想情况下,您还需要检查以下可能性:
此时您希望出现通常的警告表。可能可以通过以下方式完成:
否则,我能看到的您唯一的其他选择是使用一些自定义参数调用标准保存/写入方法之一,这些参数提示您的文档子类移动当前文档而不是实际保存它。我认为会更棘手。也许定义您自己的
NSSaveOperationType
?通过这种技术,文档系统应该理解重命名是类似保存操作的一部分,但需要进行大量实验才能确定。
There isn't much on this in the main docs. Instead, have a look at the 10.5 release notes: http://developer.apple.com/library/mac/#releasenotes/Cocoa/AppKitOlderNotes.html%23X10_5Notes under the heading "NSDocument Checking for Modified Files At Saving Time"
(In the case of Xcode, it has a long history and I wouldn't be surprised if if doesn't use
NSDocument
for files within the project)It is worth noting that moving a file does not change its modification date, so calling
-setFileModificationDate:
is unlikely to have any effect.So one possibility could be to bypass
NSDocument
's usual warning like so:Ideally you also need to check for the possibility of:
At that point you want the usual warning sheet to come up. Could probably be accomplished by something like:
Otherwise, your only other choice I can see is to call one of the standard save/write methods with some custom parameters that prompt your document subclass to move the current doc rather than actually save it. Would be trickier I think. Perhaps define your own
NSSaveOperationType
?With this technique the doc system should understand that the rename was part of a save-like operation, but it would need quite a bit of experimentation to be sure.
受到@Mike的回答的很大启发,我通过将
NSSaveOperation
重新路由到NSSaveAsOperation
来不再显示“已移动到”消息。在我的 NSDocument 子类中:saveDocumentWithDelegate:didSaveSelector:contextInfo:
来确定保存 URL 和文档类型(将它们分配给self
);如果旧 fileURL 存在,我将其移动到新位置saveDocumentWithDelegate:didSaveSelector:contextInfo:
内,我将调用重定向到[self saveToURL:self.fileURL ofType:self.fileType forSaveOperation:NSSaveAsOperation completionHandler: ...]
而不是[super saveDocumentWithDelegate:didSaveSelector:contextInfo:]
这对我有用。
Much inspired from @Mike's answer, I got the "moved to" message not to show up anymore by re-routing
NSSaveOperation
toNSSaveAsOperation
. In my NSDocument subclass:saveDocumentWithDelegate:didSaveSelector:contextInfo:
to determine the save URL and document type (assigning those toself
); if the old fileURL exists, I move that to the new locationsaveDocumentWithDelegate:didSaveSelector:contextInfo:
I redirect the call to[self saveToURL:self.fileURL ofType:self.fileType forSaveOperation:NSSaveAsOperation completionHandler: ...]
instead of[super saveDocumentWithDelegate:didSaveSelector:contextInfo:]
This works for me.
难道不能以编程方式回答用户的问题吗?
或者您可以在重命名后立即保存,这样用户就能一次性获得所有答案。
我发现这个问题已经存在并运行了一段时间,因此告诉您阅读 参考 我想不会有任何好处..
希望我能有所帮助,尽管它没有不直接解决你的问题
Isn't it possible to programmatically answer the question for the user?
Or you can save immediately after renaming, this way a user gets every answer in one go.
I see that this problem is up and running for some time, so telling you to read the reference won't do any good i guess..
Hope i helped a little bit although it doesn't fix your problem directly