首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在以编程方式重命名NSDocument文件时防止发出警告

在以编程方式重命名NSDocument文件时防止发出警告
EN

Stack Overflow用户
提问于 2010-12-03 09:17:54
回答 3查看 1.9K关注 0票数 6

我的应用程序允许用户重命名当前打开的文档。这是微不足道的,而且很好,有一个非常烦人的bug我找不出。当文件被重命名时,AppKit (善意)在用户下次试图保存文档时发出警告。用户说"OK“,一切照常进行。当应用程序外部的东西更改文档时,这是有意义的,但当文档本身实际进行更改时,就没有意义了。

代码是这样的:

代码语言:javascript
复制
-(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和文档上的修改日期就足够了,但遗憾的是,它还不够。可可仍然会产生警告。

我尝试过更改顺序(在文档上设置新URL,然后重命名文件),但这没有帮助。

我还在CocoaDev的一个旧帖子上尝试了一个用户建议的修复方法:

代码语言:javascript
复制
[self performSelector:@selector(_resetMoveAndRenameSensing)];

然而,即使这样也不能阻止警告,我猜必须有一种正确的方法来使用文档化的API来做到这一点。当用户单击项目树上的文件并将其重命名为其他文件时,Xcode如何处理这些事情。它不会警告用户重命名,因为用户实际上执行了重命名。

我该怎么办?

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2010-12-10 12:38:38

在主文档中没有太多的内容。相反,看看10.5发行说明:5注标题下的"NSDocument检查修改后的文件在保存时间“

(在Xcode的例子中,它有着悠久的历史,如果不对项目中的文件使用NSDocument,我也不会感到惊讶)

值得注意的是,移动文件不会更改其修改日期,因此调用-setFileModificationDate:不太可能产生任何效果。

因此,一种可能的做法是绕过NSDocument通常发出的类似警告:

代码语言:javascript
复制
- (void)saveDocument:(id)sender;
{
    if (wasRenamed)
    {
        [self saveToURL:[self fileURL] ofType:[self fileType] forSaveOperation:NSSaveOperation delegate:nil didSaveSelector:nil contextInfo:NULL];
        wasRenamed = NO;
    }
    else
    {
        [super saveDocument:sender];
    }
}

理想情况下,您还需要检查是否有可能:

  1. 请求应用程序重命名文档
  2. 重命名的文件然后由另一个应用程序修改/移动。
  3. 用户去保存文档

此时,您希望出现通常的警告页。很可能是通过这样的方式实现的:

代码语言:javascript
复制
- (void)renameDocumentTo:(NSString *)newName
{
    // Do the rename

    [self setFileURL:newURL];
    wasRenamed = YES; // MUST happen after -setFileURL:
}

- (void)setFileURL:(NSURL *)absoluteURL;
{
    if (![absoluteURL isEqual:[self fileURL]]) wasRenamed = NO;
    [super setFileURL:absoluteURL];
}

- (void)setFileModificationDate:(NSDate *)modificationDate;
{
    if (![modificationDate isEqualToDate:[self fileModificationDate]]) wasRenamed = NO;
    [super setFileModificationDate:modificationDate];
}

否则,我看到的唯一其他选择是使用一些自定义参数调用标准的保存/写入方法之一,这些参数提示您的文档子类移动当前文档,而不是实际保存它。我觉得会更棘手。也许定义您自己的NSSaveOperationType

使用这种技术,doc系统应该理解重命名是类似保存的操作的一部分,但是需要进行相当多的实验才能确定。

票数 3
EN

Stack Overflow用户

发布于 2015-12-11 07:45:39

很大程度上来自@Mike的回答,我得到了“移动到”消息,不再出现在重新路由NSSaveOperationNSSaveAsOperation。在我的NSDocument子类中:

  • 我重载saveDocumentWithDelegate:didSaveSelector:contextInfo:以确定保存URL和文档类型(将它们分配给self);如果存在旧的fileURL,则将其移到新的位置
  • saveDocumentWithDelegate:didSaveSelector:contextInfo:内部,我将调用重定向到[self saveToURL:self.fileURL ofType:self.fileType forSaveOperation:NSSaveAsOperation completionHandler: ...]而不是[super saveDocumentWithDelegate:didSaveSelector:contextInfo:]

这对我有用。

票数 1
EN

Stack Overflow用户

发布于 2010-12-10 12:46:58

难道不可能以编程方式为用户回答这个问题吗?或者您可以在重命名后立即保存,这样用户就可以一次得到所有答案。

我看到这个问题已经开始运行了一段时间,所以告诉你读参考文献对我来说没有任何好处。

希望我能帮上一点忙,尽管它不能直接解决你的问题

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4344031

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档