Файлы iCloud продолжают появляться после удаления

У меня есть следующая настройка: Мое приложение записывает экземпляры UIDocument в 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();
    }
}
}

После выполнения этого метода я получаю несколько уведомлений NSMetadataQueryDidFinishGatheringNotifications. Во-первых, он не содержит удаленного файла. Затем перехватывается другой NSMetadataQueryDidFinishGatheringNotification, который снова содержит удаленный файл.

Я не могу найти причину этого. Любая помощь приветствуется.


person ralphbert    schedule 20.08.2013    source источник
comment
Почему вы создаете документ, прежде чем удалить его? Это кажется ненужным. На первый взгляд, я бы сказал, что вы удаляете файл на диске, но автосохранение UIDocument срабатывает и сохраняет его снова. Вы уверены, что он закрыт, когда вы выполняете удаление? Кроме того, это зависит от того, как настроен ваш запрос, но остановка и запуск запроса при выполнении удаления кажется ненужной. Также stopQuery не обязательно останавливается немедленно (если вам это нужно, возможно, вместо этого используйте disableUpdates) - из документов для stopQuery: The receiver first completes gathering any unprocessed results.   -  person Rob Glassey    schedule 20.08.2013
comment
Спасибо за ваш ответ. Я не понял, в чем проблема, но, удалив всю потоковую и фоновую информацию, а также удалив файлы напрямую через файловый менеджер, решил проблему. для меня код кажется немного глючным и грязным. но эй, это работает ;-)   -  person ralphbert    schedule 26.08.2013
comment
Это хорошо! Если вы видите, что документы будут возрождаться в будущем, убедитесь, что у вас нет переменной экземпляра где-то еще, где есть открытая копия того же документа. Независимо от того, как часто вы удаляете с диска, если экземпляр UIDocument висит на открытой копии где-то еще в вашем приложении, автоматическое сохранение, скорее всего, воскресит его. Вы должны убедиться, что экземпляр также имеет закрытую копию файла. Но, ИМХО, многопоточность и фоновые вещи, хотя они действительно круты, когда они работают, могут быть настоящей занозой в заднице, чтобы начать работать! Есть так много ошибок, на которые стоит обратить внимание. Это того стоит.   -  person Rob Glassey    schedule 26.08.2013
comment
@RobGlassey Ваш комментарий очень помог мне, потому что уверенность в том, что UIDocument закрыта и освобождена, не только решила проблему повторного появления файла, но и нетривиальную проблему увеличения объема памяти в моем приложении. Спасибо!   -  person HuaTham    schedule 09.01.2018


Ответы (1)


Я столкнулся с подобной проблемой. Удалите инкапсуляцию экземпляра NSFileCoordinator из GCD, тогда вы сможете выполнить операцию удаления (несмотря на документацию  о том, что предпочтительнее иметь эту операцию в фоновом потоке, что странно, потому что это фактически вызывает эту проблему невозможности удаления в первую очередь)

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];
        }];
};
person yohannes    schedule 06.05.2017