使用 saveToURL:forSaveOperation:completionHandler 自动删除 UIManagedDocument 文件:

Posted

技术标签:

【中文标题】使用 saveToURL:forSaveOperation:completionHandler 自动删除 UIManagedDocument 文件:【英文标题】:UIManagedDocument file being automatically deleted with saveToURL:forSaveOperation:completionHandler: 【发布时间】:2014-05-29 22:28:25 【问题描述】:

我将 Core Data 与 UIManagedDocument 一起用于库存管理应用程序。我遇到的问题是,当我在向核心数据添加项目后使用 UIDocumentSaveForOverwriting 保存时,“saveToURL:...”方法实际上是在删除 Documents 目录中的 UIManagedDocument 文件。这仅在从新版本首次启动时发生。我创建了一个核心数据/UIManagedDocument 助手单例以在整个应用程序中使用。

这是我初始化 UIManagedDocument 实例的方法:

@interface VDFCoreDataHelper : NSObject

@property (strong, nonatomic) NSManagedObjectContext *managedObjectContext;
@property (strong, nonatomic) UIManagedDocument *managedDocument;

@implementation VDFCoreDataHelper

- (void)createManagedDocument

    NSURL *docsURL = [self getDocsURL];
    if (![[NSFileManager defaultManager] fileExistsAtPath:[docsURL path]]) 
        NSLog(@"new doc made");
        _managedDocument = [[UIManagedDocument alloc] initWithFileURL:docsURL];
        [self saveManagedDocumentForCreation];
        [self openManagedDocument];
     else 
        NSLog(@"existing doc");
        _managedDocument = [[UIManagedDocument alloc] initWithFileURL:docsURL];
        [self openManagedDocument];
    

CreateManagedDocument 在 init 方法中被调用。 我有两种保存方法。一个用于创建,一个用于覆盖。第一个在我创建托管文档时调用。

此时,我只保存了一次,并且我的文档文件夹中存在 UIManagedDocument 目录和持久存储文件。

当我要插入一个Item对象(存在一个Item实体)时,我调用这个方法:

- (void)insertManagedObject:(NSManagedObject *)object success:(void (^)(BOOL successful))successBlock

    NSManagedObjectContext *context = [self context];
    [context insertObject:object];
    NSError *error;
    [context save:&error];
    if (self.managedDocument.documentState == UIDocumentStateNormal) 
        [self.managedDocument saveToURL:[self getDocsURL] forSaveOperation:UIDocumentSaveForOverwriting completionHandler:^(BOOL success)
            successBlock(success);
        ];
    

调用“saveToURL:forSaveOperation:”for over writing后,我的托管文档目录和我的Documents文件夹中的文件都被自动删除。 managedObjectContext、Item 对象和 managedDocument 对象此时都有效。文档的 URL 指向正确的目的地,但所有文件都消失了。

在我的“insertManagedObject”方法完成后,我使用导航控制器弹回到包含列出项目的表视图的 rootViewController。我添加的数据保存在内存中,fetchedResultsController 加载它,但数据没有保存到磁盘,因为不再有持久存储。当我退出应用程序并重新进入时,什么都没有显示,并再次创建了一个新的托管文档。

只有在我第一次清除构建并启动它时才会发生这种情况。如果我启动并立即退出,然后再次进入应用程序,一切正常。就是这个“saveToURL:...: 删除我的持久存储的方法。

我已经尝试继承 UIManagedDocument 并记录错误,但它没有显示任何错误。我试过注释掉一些代码,但它们没有任何区别。

如果我不使用“saveToURL”,持久存储不会被删除,但在重新启动时,fetchResultsController.fetchObjects 返回一个空数组并尝试访问不存在的 indexPath,从而导致应用程序崩溃。

我现在正在考虑放弃 UIManagedDocument。希望有人能告诉我我可能做错了什么,或者遇到了同样的问题。

谢谢。

【问题讨论】:

【参考方案1】:

我正在为与您完全相同的问题而苦苦挣扎。但是没有找到任何帮助...

没有任何错误的删除部分让我抓狂,我几乎放弃了 UIManagedDocument。

但我做了一些真正有效的事情!

实际上我认为问题是在创建文档后尝试访问它,调用选择器:

[_document saveToURL:self.documentURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) ];

然后我所做的就是在保存文档后关闭它,获取一个新实例然后重新打开它。像这样:

[_coreDocument saveToURL:self.documentURL forSaveOperation:UIDocumentSaveForCreating completionHandler:^(BOOL success) 
                if (success) 
                    NSLog(@"Document created"); 
                    [_coreDocument closeWithCompletionHandler:^(BOOL success) 
                        if (success) 
                            NSLog(@"Closed recently created document, will open it again");
                            _coreDocument = nil;
                            _coreDocument = [[CheckinManagedDocument alloc] initWithFileURL:self.documentURL];
                            [_coreDocument openWithCompletionHandler:^(BOOL success) 
                                NSLog(@"Document oppened afer creating and closing it");
                                [self documentIsReadyForUse];
                            ];                            
                        
                    ];                    
                 else 
                    NSLog(@"Could not save the document at path: %@", self.documentURL.path);
                

            ];

【讨论】:

好的,谢谢,我最终只使用了核心数据,但我会尝试的。这在 uimanageddocument 上绝对是一种奇怪的行为。 我发现 saveToURL 上的持久性存储被删除以覆盖我的调用。

以上是关于使用 saveToURL:forSaveOperation:completionHandler 自动删除 UIManagedDocument 文件:的主要内容,如果未能解决你的问题,请参考以下文章

在使用加载数据流步骤的猪中,使用(使用 PigStorage)和不使用它有啥区别?

今目标使用教程 今目标任务使用篇

Qt静态编译时使用OpenSSL有三种方式(不使用,动态使用,静态使用,默认是动态使用)

MySQL db 在按日期排序时使用“使用位置;使用临时;使用文件排序”

使用“使用严格”作为“使用强”的备份

Kettle java脚本组件的使用说明(简单使用升级使用)