2013-08-20 44 views
3

我有以下设置: 我的应用程序将UIDocument实例写入iCloud。文件得到同步,一切工作正常。但是当我尝试删除它们时,它们不断重现。在删除文件之前,我关闭它们。下面是删除文件的代码:经过这种方法被执行了,我得到几个NSMetadataQueryDidFinishGatheringNotifications删除后iCloud文件不断重现

- (void)deleteDocumentWithName:(NSString*)name completion:(void (^)(BOOL success))completion 
{ 
[self stopQuery]; 
NSURL* toDelete = [self URLForFileWithName:name]; 

UIDocument* doc = [[UIDocument alloc] initWithFileURL:toDelete]; 

void (^deleteDocument)() = ^() { 
    // Wrap in file coordinator 
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(void) { 

     NSFileCoordinator* fileCoordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil]; 
     [fileCoordinator coordinateWritingItemAtURL:toDelete 
              options:NSFileCoordinatorWritingForDeleting 
               error:nil 
             byAccessor:^(NSURL* writingURL) { 
              // Simple delete to start 
              NSFileManager* fileManager = [[NSFileManager alloc] init]; 
              NSError* error = nil; 
              [fileManager removeItemAtURL:writingURL error:&error]; 

              if (error) { 
               LogError(@"%s - error while deleting file: %@", __PRETTY_FUNCTION__, error); 
              } 

              dispatch_async(dispatch_get_main_queue(), ^{ 
               [_files removeObject:toDelete]; 

               if (completion) { 
                completion((error == nil)); 
               } 

               [self startQuery]; 
              }); 
             }]; 
    }); 
}; 

if (doc) { 
    if (doc.documentState == UIDocumentStateNormal) { 
     [doc closeWithCompletionHandler:^(BOOL success) { 
      if (success) { 
       deleteDocument(); 
      } else { 
       if (completion) { 
        completion(NO); 
       } 
      } 
     }]; 
    } else { 
     deleteDocument(); 
    } 
} 
} 

。首先它不包含已删除的文件。然后再捕获另一个NSMetadataQueryDidFinishGatheringNotification,它包含已删除的文件。

我找不到原因。任何帮助表示赞赏。

+0

为什么在创建文档之前删除它?这似乎没有必要。在猜测中,我会说你正在删除磁盘上的文件,但UIDocument的自动保存功能正在踢入并再次保存。你确定它在执行删除时是关闭的吗?另外,这取决于您的查询设置方式,但在执行删除时停止并启动查询似乎不必要。另外stopQuery不一定会立即停止(如果你需要这个可能使用disableUpdates代替) - 来自stopQuery的文档:'接收器首先完成收集任何未处理的结果.' –

+0

感谢您的回应。我没有弄清楚问题所在,而是通过删除整个线程和背景资料,并直接删除文件来解决问题。对我来说,代码现在看起来有点bug和脏。但嘿,它的工作原理;-) – ralphbert

+3

这很好!如果您将来看到文档复活,请检查您没有其他地方有实例变量的实例变量,该实例变量具有该文档的公开副本。无论你多久删除一次磁盘,如果UIDocument实例挂在应用程序中其他位置的打开副本上,自动保存可能会重新启动它。您需要确保* instance *已将文件的副本关闭。但是,恕我直言,线程和背景的东西,虽然它真的很酷,但它可以是一个正确的工作屁股疼痛!有很多需要注意的问题。这是值得的。 –

回答

0

我面临类似的问题。从GCD中除去封装的NSFileCoordinator实例化,那么你将能够执行删除操作(尽管文档最好在后台线程中执行此操作,这很奇怪,因为这样做实际上会导致这个无法删除的问题首先)

void (^deleteDocument)() = ^() { 
    NSFileCoordinator* fileCoordinator = [[NSFileCoordinator alloc] initWithFilePresenter:nil]; 
     [fileCoordinator coordinateWritingItemAtURL:toDelete 
      options:NSFileCoordinatorWritingForDeleting 
      error:nil 
      byAccessor:^(NSURL* writingURL) { 
      // Simple delete to start 
      NSFileManager* fileManager = [[NSFileManager alloc] init]; 
      NSError* error = nil; 
      [fileManager removeItemAtURL:writingURL error:&error]; 

      if (error) { 
      LogError(@"%s - error while deleting file: %@", __PRETTY_FUNCTION__, error); 
      } 

      [_files removeObject:toDelete]; 

      if (completion) { 
      completion((error == nil)); 
      } 

      [self startQuery]; 
     }]; 
};