Spotlight插件读取NSDocument导致"拒绝文件写入数据"控制台错误

时间:2015-05-04 13:21:45

标签: cocoa nsdocument appstore-sandbox spotlight spotlight-plugin

我有一个基于沙盒的NSDocument应用程序,带有Spotlight插件,可以为我的自定义文档编制索引。

在测试期间,我注意到Spotlight插件在索引文档时将大量错误记录到控制台:

5/4/15 3:11:18.765 PM sandboxd[432]: ([579]) mdworker(579) deny file-write-data 
  /Users/test/Desktop/test.document 
  (import fstype:hfs fsflag:480D000 flags:240000005E diag:0 isXCode:0
    uti:com.test.document 
  plugin:/TestApp.app/Contents/Library/Spotlight/TestApp Spotlight Importer.mdimporter - 
  find suspect file using: sudo mdutil -t 407144)

好像插件试图写入它索引的文件(尽管它只有只读访问权限)。

在我的Spotlight插件实现中,我没有做任何特别的事情来写入文档。我所做的就是初始化我的NSDocument子类以从文档中读取:

[[TTCustomDocument alloc] initWithContentsOfURL:url ofType:contentType error:outError];

这是堆栈跟踪:

Thread 4:
0   libsystem_kernel.dylib          0x00007fff9015ee92 __mac_syscall + 10
1   libsystem_sandbox.dylib         0x00007fff910140b0 sandbox_check + 206
2   AppKit                          0x00007fff8f75fc38 -[NSDocument _autosavingPossibilityConcern] + 213
3   AppKit                          0x00007fff8f75fb02 -[NSDocument _checkAutosavingPossibilityAndReturnError:] + 60
4   AppKit                          0x00007fff8f75f9cf -[NSDocument _checkAutosavingAndReturnError:] + 26
5   AppKit                          0x00007fff8f75f97e -[NSDocument _checkAutosavingAndUpdateLockedState] + 26
6   AppKit                          0x00007fff8f75e420 -[NSDocument _initWithContentsOfURL:ofType:error:] + 319
7   AppKit                          0x00007fff8f75e056 -[NSDocument initWithContentsOfURL:ofType:error:] + 230

看起来自动检查以某种方式试图写入文档。

我能做些什么吗?是否有某种只读模式来打开NSDocument?

更新

重现:

  1. 创建一个新的Xcode项目:"基于Cocoa文档的应用程序"
  2. 添加Spotlight插件
  3. NSDocument实施和Spotlight插件的代码位于:https://gist.github.com/anonymous/c4929586dfa11a473673

1 个答案:

答案 0 :(得分:0)

好的,那么-[TTCustomDocument initWithContentsOfURL:ofType:error:]或其他任何自定义初始化代码以及-readFromURL:ofType:error及相关代码的代码在哪里?您可能会从其中一个(init ...和/或read ...)方法触发某些内容,导致文档被标记为脏(有未保存的更改),这会导致自动保存系统被触发。这是TTCustomDocument课程中的不当行为。

我的猜测是你正在触发一些注册文档撤消管理器更改的内容。如果它是核心数据文档并且您正在设置一些初始数据,那么很容易做到;如果您以调用自己的撤消感知漏斗方法之一的方式设置初始数据,也很容易做到。最简单的解决方法(文档推荐)是在更改之前调用[self.undoManager disableUndoRegistration];和`[self.undoManager enableUndoRegistration];在变化之后和返回自我之前。