在不关闭 UIDocument 的情况下重命名文档

Rename document without closing UIDocument

如何在不关闭并重新打开文档的情况下使用打开的 UIDocument 重命名文档文件?关闭(保存)、移动和重新打开文档的时间太长。

我有以下移动文件的代码:

NSFileCoordinator* fileCoordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
[fileCoordinator coordinateWritingItemAtURL:oldPath
                                    options:NSFileCoordinatorWritingForMoving
                           writingItemAtURL:newPath
                                    options:NSFileCoordinatorWritingForReplacing
                                      error:&coordinatorError
                                 byAccessor:^(NSURL *newURL1, NSURL *newURL2) {
  // Rename the file.
  NSFileManager* fileManager = [NSFileManager defaultManager];
  [fileCoordinator itemAtURL:oldPath willMoveToURL:newPath];
  [fileManager moveItemAtURL:newURL1 toURL:newURL2 error:nil];
  [fileCoordinator itemAtURL:oldPath didMoveToURL:newPath];
}];

根据文档 UIDocument 实现 presentedItemDidMoveToURL: 以更新其 fileURL(参见 https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIDocument_Class/

但是,当在文档打开的情况下调用上面的代码时,它会挂起,大概是在等待对 oldPath (-[NSFileCoordinator(NSPrivate) _blockOnAccessClaim:]) 的锁定。如果没有活人,工作正常 UIDocument.

相关,最佳答案建议关闭并重新打开UIDocumentWhat is the proper way to move a UIDocument to a new location on the file-system

解决方案是使用后台队列来避免死锁:

dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^(void) {

  NSError *coordinatorError = nil;

  NSFileCoordinator* fileCoordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil];
  [fileCoordinator coordinateWritingItemAtURL:oldPath
                                    options:NSFileCoordinatorWritingForMoving
                           writingItemAtURL:newPath
                                    options:NSFileCoordinatorWritingForReplacing
                                      error:&coordinatorError
                                 byAccessor:^(NSURL *newURL1, NSURL *newURL2) {
    // Rename the file.
    NSFileManager* fileManager = [NSFileManager defaultManager];
    [fileCoordinator itemAtURL:oldPath willMoveToURL:newPath];
    [fileManager moveItemAtURL:newURL1 toURL:newURL2 error:nil];
    [fileCoordinator itemAtURL:oldPath didMoveToURL:newPath];
  }];

});