【发布时间】:2015-05-03 15:15:04
【问题描述】:
我的 Mac 应用程序会复制用户拖入的文件。该应用程序是沙盒化的。我现在有一个错误,我可以在 Xcode 中可靠地重现它,但我无法追踪它的来源。
当我添加一定数量的文件时,应用程序突然无法访问后面的文件。所有源文件都来自同一个父目录的下一级,并且其间的所有文件夹都具有相同的权限,并通过ls -l 验证。该应用保留了一个应用范围的书签到Destination Directory,在创建.directoryName 和开始文件复制之前访问它。
我得到错误:
Error Domain=NSCocoaErrorDomain Code=513 “无法复制“Filename.ext”,因为您没有访问“.directoryName”的权限。” UserInfo=0x6080000eaf80 {NSSourceFilePathErrorKey=/Users/Username/父目录/Subdir/Filename.ext, NSUserStringVariant=( 复制 ), NSDestinationFilePath=/Users/Username/Desktop/Destination Directory/.directoryName/Filename.ext, NSFilePath=/Users/Username/Parent Directory/Subdir/Filename.ext, NSUnderlyingError=0x6080004567a0 "操作无法完成。操作不允许”}
我在调试时做了以下事情:
- 尝试在退出并重新启动后自行添加
Subdir/Filename.ext,效果很好 - 已验证(使用
lsof和 Activity Monitor)我没有泄漏文件句柄(我知道这在过去给我造成了类似的问题) - 通过符号断点验证,每次调用
-[NSURL startAccessingSecurityScopedResource]都与调用-[NSURL stopAccessingSecurityScopedResource](及其CF等效项)进行平衡 - 确定
Filename.ext和其他失败的文件在没有其他文件的情况下添加成功 - 在调试器内外,Debug 和 Release 版本的行为相同
- 我尝试以 root 身份运行,但我的应用程序无法以这种方式运行。在调试器中运行时,我得到一个
EXC_BAD_INSTRUCTION异常,并在命令行上使用sudo运行它会导致崩溃(可能是同一个)
这种行为似乎表明某种资源泄漏,但我还没有检测到。有什么想法可能导致这种情况吗?
更新
我还没有准备好宣布答案,但是在用户将文件放入应用程序后,我开始在代码的不同部分收到这些权限错误。我注意到在日志中稍稍向上,我会看到如下消息:
使用粘贴板中 itemIdentifier (1) 的沙盒扩展失败!
追查这个错误让我想到了一个别人问的问题:Sandboxed Mac app exhausting security scoped URL resources
不幸的是,accepted answer 说(释义)“强硬的 noogies”。似乎 Cocoa 和沙盒机制本身正在泄漏安全范围令牌(尽管我无法使用符号断点进行验证,并且不知道没有其他方法可以检查)。在沙盒文件上执行一定(未知)数量的文件操作后,您将开始收到此错误,唯一的解决方案是退出并重新启动。
我希望至少有某种方法可以在用户关闭时提示用户重新启动,但我不确定有什么方法可以测量这些句柄中有多少正在使用中。或者,更好的是,如果我可以在处理完删除的文件后手动清理,但我不确定它是如何工作的,因为我需要使用 NSFilenamesPboardType 粘贴板类型来获取多个文件的路径。我尝试从这些创建NSURLs 并停止安全范围访问,但这没有任何效果。
更新 2
我为此提交了 DTS 票证,因为它会影响用户并且没有明确的解决方法。当我发现更多信息时,我会更新问题(也许会给出答案?)。
Apple DTS 团队的回应
显然,这是一个已知问题,没有可用的解决方法。我提交了一个雷达:rdar://20652066,如果你想欺骗它。
【问题讨论】:
标签: objective-c macos cocoa nsfilemanager appstore-sandbox