我将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];
    }
}

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

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

当我要插入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:”进行覆盖后,我的托管文档目录和“文档”文件夹中的文件将全部自动删除。此时,managedObjectContext,Item对象和managedDocument对象均有效。文档的URL指向正确的目的地,但是所有文件都消失了。

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

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

我已经尝试将UIManagedDocument子类化并记录错误,但是它没有显示任何错误。我尝试注释掉一些代码,但是它们没有任何区别。

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

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

谢谢。

最佳答案

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

没有任何错误的删除部分使我发疯,并且我几乎放弃了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);
                }

            }];

10-07 12:27