2

我有一个带有 iCloud 同步的项目,但它根本无法正常工作。首先,我得到一组更改的对象,然后将它们转换为 CSV 字符串(这将是云中 UIDocuments 的内容),然后将它们上传到 iCLoud。如果我有少于 400 个对象,一切都很好,但如果我有更多 - 应用程序挂起。

我尝试使用本地自动释放池,我已将大数组拆分为较小的数组。但这没有帮助。

将大量 UIDocuments 上传到 iCloud 的最佳方式是什么?我的上传方法:

- (void)pushChangesToCloud:(NSArray *)changedObjects {

    for (ObjectClass *someObject in changedObjects) {
        NSURL *pathToSyncDoc = [[self urlForDocumentsFolderIniCloud] URLByAppendingPathComponent:someObject.name];

        CustomUIDocument *syncDoc = [[[CustomUIDocument alloc] initWithFileURL:pathToSyncDoc] autorelease];
        //   converting object to CSV string
        NSString *csvContents = [SomeClass convertObjectToCSV:someObject];      
        syncDoc.documentContent = csvContents;

        [syncDoc saveToURL:[syncDoc fileURL] 
          forSaveOperation:UIDocumentSaveForCreating 
         completionHandler:^(BOOL success) {
             if (success) {
                 NSLog(@"YAY!");
             } else {
                 NSLog(@" D: "); 
             }
         }];
    }
}

在此先感谢并为我的英语感到抱歉。

4

2 回答 2

1

感谢@Eimantas 的帮助,我终于找到了我的问题。他对超载队列的看法是正确的。由于“saveToUrl:forSaveOperation:completionHandler:”是 i/o 操作,队列创建了很多线程(对于每个 UIDocument)并且应用程序挂起。

我在自定义 UIDocument 中重载了“saveToUrl:forSaveOperation:completionHandler:”方法(以避免在并发线程中保存文档):

- (void)saveToURL:(NSURL *)url forSaveOperation:(UIDocumentSaveOperation)saveOperation completionHandler:(void (^)(BOOL))completionHandler {
NSError *contentsError = nil;
NSError *attributesError = nil;
NSError *savingError = nil;

[self writeContents:[self contentsForType:self.fileType error:&contentsError] andAttributes:[self fileAttributesToWriteToURL:url forSaveOperation:saveOperation error:&attributesError] safelyToURL:url forSaveOperation:saveOperation error:&savingError];

NSLog(@"SAVING ERRORS: contents error - %@, attributes error - %@, saving error - %@",[contentsError localizedDescription],  [attributesError localizedDescription], [savingError localizedDescription]);
}

然后我使用自己的串行队列来执行所有保存操作。首先,您需要像 iVar 一样添加它:

dispatch_queue_t mySerialQueue;

然后在 init 方法中创建它:

myCustomQueue = dispatch_queue_create("com.whatever.MyAwesomeQueue", DISPATCH_QUEUE_SERIAL);

用它来保存:

dispatch_async(mySyncQueue, ^{
    // do saving stuff
});

然后在 dealloc 中释放它:

dispatch_release(mySyncQueue);

在此更改后,我没有任何问题。

希望这可以帮助!(对不起我的英语:>)

于 2012-06-13T13:32:09.550 回答
1

Dmitry,您覆盖 saveToURL: 的方式是不安全的。UIDocument saveToURL 的默认实现将使用文件协调来确保无处不在的守护进程知道您在写入磁盘的内容和时间。您的实现不进行文件协调,除非您在 writeContents:, 中进行文件协调(您不应该这样做)。

请参阅 UIDocument 的 saveToURL 文档的讨论部分:https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIDocument_Class/UIDocument/UIDocument.html#//apple_ref/occ/instm/UIDocument/saveToURL: forSaveOperation:completionHandler :

于 2013-06-26T19:48:11.483 回答