dan*_*elv 13 macos cocoa sandbox objective-c
我正在开发一个Mac应用程序,它使用NSOpenPanel提示用户输入文件.应用程序是沙箱(在OSX 10.9.4上测试).我注意到如果我打开大量文件(~3000),打开的面板会开始向日志发出错误.如果我尝试在chucks中打开少量文件多次,也会发生这种情况.
在第一次出现错误之后,每次再次使用NSOpenPanel打开文件时,无论文件数量多少,都会再次生成这些错误(直到应用程序关闭).
错误消息如下所示:
TestPanel[98508:303] __41+[NSSavePanel _consumeSandboxExtensions:]_block_invoke: sandbox_consume_fs_extension failed
Run Code Online (Sandbox Code Playgroud)
我试图打开的每个文件一行.
我设法用一个简单的应用程序重现这种行为:一个带有单个按钮的沙盒应用程序调用以下代码:
NSOpenPanel* panel = [NSOpenPanel openPanel];
[panel setAllowsMultipleSelection:YES];
[panel setCanChooseDirectories:NO];
[panel setCanChooseFiles:YES];
[panel beginSheetModalForWindow:[self window] completionHandler:^(NSInteger result) {
NSLog(@"%lu", [panel.URLs count]);
}];
Run Code Online (Sandbox Code Playgroud)
错误出现在代码到达完成处理程序之前.
似乎我仍然可以从完成处理程序中的面板中获取URL,但它确实污染了系统日志.
编辑:
似乎此问题与NSOpenPanel/NSSavePanel面板没有直接关系.使用drap/drop with files时会发生非常类似的事情.像这样的东西:
- (NSDragOperation)draggingEntered:(id <NSDraggingInfo>)sender {
...
NSPasteboard *pboard = [sender draggingPasteboard];
if ([[pboard types] containsObject:NSURLPboardType]) {
NSArray *urls = [pboard readObjectsForClasses:@[[NSURL class]] options:nil];
}
...
}
Run Code Online (Sandbox Code Playgroud)
拖动大量文件时会生成以下日志消息("魔术"数字似乎在2900左右):
Consume sandbox extension for itemIdentifier (2937) from pasteboard failed!
Run Code Online (Sandbox Code Playgroud)
与NSOpenPanel一样,在第一次出现之后,每个丢弃的文件都会在日志中生成相同的错误.
编辑2:
@mahal tertin的回复向我指出了正确的方向.问题确实存在于文件数量和安全范围URL资源有限的事实上.
但是,似乎找不到合理的解决方案.问题是,当用户在NSOpenPanel上单击"确定"(或删除拖放感知控件上的文件)时,操作系统已经尝试创建这些安全范围的URL并隐式调用startAccessingSecurityScopedResource您.因此,如果用户尝试打开的文件超过限制,则资源将耗尽,唯一的选择是关闭并重新启动应用程序.
调用stopAccessingSecurityScopedResource返回的URL似乎可以释放资源,但Apple 官方开发者论坛上的代表不鼓励这种解决方案(链接在登录后面).
似乎该应用程序受用户的摆布,不打开太多文件.这甚至不是立刻,因为没有批准的方式来释放这些资源.您可以在文档中警告用户,甚至可以通过应用程序内警告警告用户,但是无法防止他们弄乱应用程序并强制重新启动.
因此,如果应用程序运行时间足够长并且用户不断打开文件,则应用程序最终将无法使用.
仍在寻找合理的解决方案.
在高低搜索并在各个地方询问之后,我将结束这个问题并得出结论,没有答案或解决方案.我发布有关此信息的已知信息以供将来参考.
建议的所有解决方案只是可以最小化问题的解决方法,并尝试引导用户不要尝试打开太多文件.但实际上没有任何办法可以解决这个问题.
以下是有关此问题的已知事实:
startAccessingSecurityScopedResource对于使用NSOpenPanel 打开的文件会自动调用(或者拖动/什么都没有关闭这些资源stopAccessingSecurityScopedResource开放面板检索到的所有URL将释放这些资源,但Apple不鼓励这种做法,称它可能与未来的解决方案不兼容苹果似乎真的放弃了这个,沙盒实施似乎非常草率和短视.
您遇到的行为是因为安全范围资源有限:
NSURL - (BOOL)startAccessingSecurityScopedResource告诉
如果泄漏了足够的内核资源,您的应用程序将无法将文件系统位置添加到其沙箱中...
目前的限制大致与您的经历相同.请参阅: 安全范围书签的当前内核资源限制是什么?
为了防止它:
| 归档时间: |
|
| 查看次数: |
1038 次 |
| 最近记录: |