macos - NSFileWrapper 有时返回 nil

标签 macos cocoa nsdocument nsfilewrapper

我正在使用 NSFileWrapper 作为我的包文档。有时,当我请求包内文件的数据时,我得到nil

这是我查询包内文件数据的方法:

- (NSData*) dataOfFile(NSString*)filename {
    NSFileWrapper *fileWrapper = [self.documentFileWrapper.fileWrappers objectForKey:filename];
    return fileWrapper.regularFileContents; // This returns nil sometimes. Why?
}

此方法最终开始对某些文件(不是全部)返回 nil。遗憾的是,我未能一致地重现该问题。

如果有帮助,这就是我打开包裹的方式:

- (BOOL) readFromFileWrapper:(NSFileWrapper *)fileWrapper ofType:(NSString *)typeName error:(NSError *__autoreleasing *)outError {
    self.documentFileWrapper = fileWrapper;
    return YES;
}

这是我更新包内文件数据的方法:

- (void) updateFile:(NSString*)filename withData:(NSData*)data {
    SBFileWrapper *fileWrapper = [self.documentFileWrapper.fileWrappers objectForKey:filename];
    if (fileWrapper) {
        [self.documentFileWrapper removeFileWrapper:fileWrapper];
    }
    NSFileWrapper *fileWrapper = [[SBFileWrapper alloc] initRegularFileWithContents:data ];
    fileWrapper.preferredFilename = filename;
    [self.documentFileWrapper addFileWrapper:fileWrapper];
}

这就是我保存包的方式:

- (NSFileWrapper*) fileWrapperOfType:(NSString *)typeName error:(NSError *__autoreleasing *)outError {
    return self.documentFileWrapper;
}

为什么会发生这种情况?有什么办法可以预防吗?

regularFileContents 的文档似乎在谈论这个问题:

This method may return nil if the user modifies the file after you call readFromURL:options:error: or initWithURL:options:error: but before NSFileWrapper has read the contents of the file. Use the NSFileWrapperReadingImmediate reading option to reduce the likelihood of that problem.

但我不明白必须更改上面的代码中的哪些内容才能防止出现这种情况。

失败的实验

如果 regularFileContents 返回 nil,我尝试保存文档,但之后它仍然返回 nil。像这样:

- (NSData*) dataOfFile(NSString*)filename {
    NSFileWrapper *fileWrapper = [self.documentFileWrapper.fileWrappers objectForKey:filename];
    NSData *data = fileWrapper.regularFileContents;
    if (!data) {
            [self saveDocument:nil];
            fileWrapper = [self.documentFileWrapper.fileWrappers objectForKey:filename];
            data = fileWrapper.regularFileContents;
    }
    return data;
}

最佳答案

没有足够的代码来查看到底发生了什么。然而,根本原因是 NSFileWrapper 正如其名称所暗示的那样:一个代表文件或目录的对象。因此,实际文件或目录很容易与内存中的对象“不同步”。每当 NSFileWrapper 确定发生这种情况时,它会对某些操作返回 nil。解决方案是使 NSFileWrapper 对象短暂存在。在需要时创建并打开,然后尽快保存并关闭。

特别是,您的代码似乎长时间保留了指向包目录包装器的指针,并假设它始终有效。如果目录因任何原因发生更改,则情况并非如此。重新编码,以便每次需要时都获得一个新的包目录包装器,并且问题应该消失。

关于macos - NSFileWrapper 有时返回 nil,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12911438/

相关文章:

macos - 我应该担心 python 3.6 没有代码签名吗?

swift - NSDocument:如何保存和恢复文档的窗口位置?

objective-c - NSDocument 应用程序和文件扩展名

objective-c - NSSlider 多次撤销注册

cocoa - applicationDidFinishLaunching : executing after NSDocument is loaded from NIB

objective-c - 打印 NSDocument

xcode - imwrite 在 OpenCV 中抛出编译错误

macOS 终端 : `ls` sorts results with capitalised names first

excel - 如何确定我的 VB 代码是否在 Office 2016 for Mac 上运行?

objective-c - 在 os x 应用程序中进入全屏模式时自定义 View 动画