Большой массив UIDocuments для iCloud

У меня есть проект с синхронизацией 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: "); 
             }
         }];
    }
}

Заранее спасибо и извините за мой английский.

2 ответа

Решение

Я наконец понял свою проблему, спасибо @Eimantas за его помощь. Он был прав насчет перегруженной очереди. Так как "saveToUrl:forSaveOperation: завершениеХандлер:" является операцией ввода-вывода, очередь создала много потоков (для каждого UIDocument) и приложение зависает.

Я перегрузил метод "saveToUrl:forSaveOperation: завершение и завершение:" в своем пользовательском UIDocument (чтобы не сохранять документы в параллельных потоках):

- (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);

После этих изменений у меня нет проблем с этим.

Надеюсь это поможет! (и извините за мой английский:>)

Дмитрий, способ, которым вы переопределяете saveToURL: небезопасен. Реализация UIDocument saveToURL по умолчанию будет использовать координацию файлов, чтобы убедиться, что демон ubiquity знает, что и когда вы записываете на диск. Ваша реализация не координирует файлы, если вы не координируете файл в writeContents:, (что не должно быть).

См. Раздел обсуждения документов saveToURL в UIDocument по адресу: https://developer.apple.com/library/ios/documentation/UIKit/Reference/UIDocument_Class/UIDocument/UIDocument.html:

Другие вопросы по тегам