我的Mac应用程序会复制用户拖入的文件。该应用程序是沙盒。我现在有一个bug,我可以在Xcode中可靠地重现,但是我无法追踪它的来源。
当我添加一定数量的文件时,应用程序突然无法访问后来的文件。所有源文件都从同一个父目录向下一级,并且其间的所有文件夹都具有相同的权限,并使用ls -l
进行验证。该应用程序会保留应用程序范围的Destination Directory
书签,在创建.directoryName
并开始文件复制之前可以访问该书签。
我收到错误:
错误Domain = NSCocoaErrorDomain Code = 513“”Filename.ext“无法复制,因为您无权访问”.directoryName“。” UserInfo = 0x6080000eaf80 {NSSourceFilePathErrorKey = / Users / Username / Parent Directory / 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
和活动监视器)我没有泄漏文件句柄(我知道过去曾为我造成类似问题)-[NSURL startAccessingSecurityScopedResource]
与调用-[NSURL stopAccessingSecurityScopedResource]
(以及他们的CF
等价物)的平衡Filename.ext
和其他失败的文件在没有其他文件的情况下成功添加EXC_BAD_INSTRUCTION
异常,并在命令行上使用sudo
运行它会导致崩溃(可能是同一个)这种行为似乎表明某种资源泄漏,但它并不是我能够检测到的任何东西。还有什么想法可能导致这个问题吗?
更新
我还没有准备好宣布答案,但是在用户将文件放入应用程序后,我开始在代码的不同部分出现这些权限错误。我注意到日志的一些方法,我会看到如下消息:
从粘贴板使用itemIdentifier(1)的沙箱扩展名失败!
追踪此错误导致我提出其他人问的问题:Sandboxed Mac app exhausting security scoped URL resources
不幸的是,accepted answer说(释义)“强硬的no no”。似乎Cocoa和沙盒机制本身正在泄漏安全范围令牌(虽然我无法通过符号断点进行验证,并且知道没有其他方法可以检查)。在沙盒文件上执行某些(未知)数量的文件操作后,您将开始收到此错误,唯一的解决方案是退出并重新启动。
我希望至少有一些方法可以提示用户在关闭时重新启动,但我不确定是否有任何方法可以衡量这些句柄的使用情况。或者,更好的是,如果我在完成处理删除的文件后手动清理,但我不确定这是如何工作的,因为我需要使用NSFilenamesPboardType
粘贴板类型来获取多个文件的路径。我尝试从这些创建NSURL
并停止安全范围访问,但这没有效果。
更新2
我为此提交了一张DTS票据,因为它正在影响用户,并且没有明确的解决方法。我会更新问题(也许会给出答案?),因为我发现了更多。
来自Apple DTS团队的回复
显然,这是一个已知问题,没有可用的解决方法。我提交了一个雷达:rdar://20652066,如果你想欺骗它。
答案 0 :(得分:0)
这是在El Capitan(10.11)版本中修复的(可能是第一版,但我不确定)。当我针对更新的SDK构建我的应用程序时,行为恢复正常。