我指的是文档提供程序扩展的WWDC2014示例应用程序NewBox。我使用来自NeBox应用程序的以下代码,将文档从文档提供程序导入到我的应用程序中。
- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentAtURL:(NSURL *)url {
BOOL startAccessingWorked = [url startAccessingSecurityScopedResource];
NSURL *ubiquityURL = [[NSFileManager defaultManager] URLForUbiquityContainerIdentifier:nil];
NSLog(@"ubiquityURL %@",ubiquityURL);
NSLog(@"start %d",startAccessingWorked);
NSFileCoordinator *fileCoordinator = [[NSFileCoordinator alloc] init];
NSError *error;
[fileCoordinator coordinateReadingItemAtURL:url options:0 error:&error byAccessor:^(NSURL *newURL) {
NSData *data = [NSData dataWithContentsOfURL:newURL];
NSLog(@"error %@",error);
NSLog(@"data %@",data);
}];
[url stopAccessingSecurityScopedResource]; }
coordinateReadingItemAtURL方法的应用程序完全挂起。任何输入都会很有帮助。
发布于 2014-12-18 11:12:51
我也注意到了NewBox应用程序中的这个问题,并决定追踪它。因此,这个应用程序中有两个扩展:文档选择器和文件提供程序。长话短说,当他们试图访问应用程序的文档存储文件夹中的文件时,两者之间存在竞争条件。
在我看来,追踪问题的最简单方法是将NSLog()放在一堆位置上。然而,问题是扩展生成的调试输出在Xcode控制台中是不可见的。好消息是,您可以通过单击调试->打开系统日志菜单,在iOS模拟器应用程序中打开控制台。这将显示所有类型的调试消息,包括由扩展生成的消息。您可以找到有关扩展调试here的更多信息。
通过使用此方法,可以很容易地意识到执行被卡在文件提供程序的startProvidingItemAtURL方法中。更具体地说,下面这行代码会导致死锁:
[self.fileCoordinator coordinateWritingItemAtURL:url options:0 error:&error byAccessor:^(NSURL *newURL) {为什么会这样呢?查看coordinateWritingItemAtURL的文档
如果url参数指定文件,则为
:此方法等待完全相同文件的其他读取器和写入器完成正在进行的操作。
您提到的函数documentPicker调用一个读操作,而读操作又触发一个写操作。这是一个死锁。我想修复它的最简单的方法是避免在文件提供程序中使用coordinateWritingItemAtURL。
发布于 2014-12-10 20:19:40
根据文档:
在同一线程上调用传入的访问器块之前,这些方法中的每一个都在调用它们的同一线程上同步等待,而不是异步等待并在特定队列上调度块的调用。
发布于 2015-02-13 01:44:59
Apple建议您不要在此方法中使用文件协调。系统已经保证在此方法执行时没有其他进程可以访问该文件。这是造成这种僵局的唯一原因。
请参考this documentation了解更多详细信息。
https://stackoverflow.com/questions/25637111
复制相似问题