CoreData,UIManagedDocument和空持久存储 [英] CoreData, UIManagedDocument and empty Persistent Store

查看:159
本文介绍了CoreData,UIManagedDocument和空持久存储的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 UIManagedDocument 来读取和写入 CoreData 。我有文档类。这是来自某些教程的文档:

I'm using UIManagedDocument to reading and writing to CoreData. I have Document class. This is a document from some tutorial:

.h

#import <Foundation/Foundation.h>
#import <CoreData/CoreData.h>

typedef void (^OnDocumentReady) (UIManagedDocument *document);

@interface Document : NSObject

@property (strong, nonatomic) UIManagedDocument *document;

+ (Document *)sharedDocument;
- (void)performWithDocument:(OnDocumentReady)onDocumentReady;

@end

.m

@interface Document ()
- (void)objectsDidChange:(NSNotification *)notification;
- (void)contextDidSave:(NSNotification *)notification;
@end;

@implementation Document

@synthesize document = _document;

static Document*_sharedInstance;

+ (Document *)sharedDocument
{
    static dispatch_once_t once;
    dispatch_once(&once, ^{
        _sharedInstance = [[self alloc] init];
    });

    return _sharedInstance;
}

- (id)init {
    self = [super init];
    if (self) {
        NSURL *url = [[[NSFileManager defaultManager] URLsForDirectory:NSDocumentDirectory inDomains:NSUserDomainMask] lastObject];
        url = [url URLByAppendingPathComponent:@"Document"];
        self.document = [[UIManagedDocument alloc] initWithFileURL:url];

        NSDictionary *options = [NSDictionary dictionaryWithObjectsAndKeys:
                                 [NSNumber numberWithBool:YES], NSMigratePersistentStoresAutomaticallyOption,
                                 [NSNumber numberWithBool:YES], NSInferMappingModelAutomaticallyOption, nil];
        self.document.persistentStoreOptions = options;

        // Register for notifications
        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(objectsDidChange:)
                                                     name:NSManagedObjectContextObjectsDidChangeNotification
                                                   object:self.document.managedObjectContext];

        [[NSNotificationCenter defaultCenter] addObserver:self
                                                 selector:@selector(contextDidSave:)
                                                     name:NSManagedObjectContextDidSaveNotification
                                                   object:self.document.managedObjectContext];
    }
    return self;
}

- (void)performWithDocument:(OnDocumentReady)onDocumentReady
{
    void (^OnDocumentDidLoad)(BOOL) = ^(BOOL success) {
        onDocumentReady(self.document);
    };

    if (![[NSFileManager defaultManager] fileExistsAtPath:[self.document.fileURL path]]) {
        [self.document saveToURL:self.document.fileURL
                forSaveOperation:UIDocumentSaveForCreating
               completionHandler:OnDocumentDidLoad];
    } else if (self.document.documentState == UIDocumentStateClosed) {
        [self.document openWithCompletionHandler:OnDocumentDidLoad];
    } else if (self.document.documentState == UIDocumentStateNormal) {
        OnDocumentDidLoad(YES);
    }
}

- (void)objectsDidChange:(NSNotification *)notification
{
#ifdef DEBUG
    NSLog(@"NSManagedObjects did change.");
#endif
}

- (void)contextDidSave:(NSNotification *)notification
{
#ifdef DEBUG
    NSLog(@"NSManagedContext did save.");
#endif
}

@end

然后在 ViewController 我有 NSURLConnection

-(void)connectionDidFinishLoading:(NSURLConnection *)connection {
    DataParser *parser = [[DataParser alloc] init];
    [parser startParsingData:self.myMutableData withContext:self.moc];
}

我在这里打开文档:

-(void)initDocument {
    if (!self.moc) {
        [[Document sharedDocument] performWithDocument:^(UIManagedDocument *document) {
            self.moc = document.managedObjectContext;
            [[NSNotificationCenter defaultCenter] postNotificationName:UIDocumentStateChangedNotification object:self];

            NSURLRequest *request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:@"someURL"] cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60];
            [NSURLConnection connectionWithRequest:request delegate:self];
        }];
    }
}

然后我尝试解析数据:

-(void)startParsingData:(NSData*)data withContext:(NSManagedObjectContext*)context {
    self.moc = context;
    self.startDate = [NSDate date];
    NSXMLParser *parser = [[NSXMLParser alloc] initWithData:data];
    parser.delegate = self;
    [parser parse];
}

ant尝试在 XML之后将其加载到核心数据解析:

-(void)parser:(NSXMLParser *)parser didEndElement:(NSString *)elementName namespaceURI:(NSString *)namespaceURI qualifiedName:(NSString *)qName {
    if([elementName isEqualToString:@"Item"]) {
            [self.moc performBlockAndWait:^{
                TestEntity *te = [NSEntityDescription insertNewObjectForEntityForName:@"TestEntity" inManagedObjectContext:self.moc];
                te.surname = @"5433fds";
                te.name = @"5342fdsfsd";
            }];
    }
}

我看到日志:

2014-01-24 16:21:21.692 Ce[85149:70b] NSManagedObjects did change.
2014-01-24 16:21:36.696 Ce[85149:70b] NSManagedContext did save.

所以我假设这应该在sqlite文件,但是当我尝试读它是完全空。 awl 文件有一些更大的大小,但persistentStore有0行。为什么?

So i assume that this should be in sqlite file, but when I try to read it is completely empty. awl file have some bigger size, but persistentStore have 0 rows. Why?

推荐答案

当您第二次启动应用程式时会发生什么情况,您能看到应用程式中的资料吗?

What happens when you launch the app a second time, can you see the data in your app?

在iOS 7中,SQLite现在已开启日志功能。我不知道日志是否导致混乱(数据是有的,但在sqlite文件中还没有)。

In iOS 7, SQLite now has journaling turned on. I wonder if the journalling is causing a confusion (data is there but not in the sqlite file yet).

我也想知道为什么你使用 UIManagedDocument 。看来你正在使用单核模式(这是坏),然后使用 UIManagedDocument 在单一模式(更糟糕的)中的Core Data。

I would also question why you are using a UIManagedDocument. It appears you are using Core Data in a Singleton pattern (which is bad) and then using UIManagedDocument in that singleton pattern (worse).

UIManagedDocument 适用于基于文档的应用程序。你可能是在该类中的一些自动化功能犯了错误,如果你构建一个标准的Core数据栈,将很容易清除。

UIManagedDocument is intended for document based apps. You are probably running foul of some of the "automated" features inside of that class that would be easily cleared up if you built a standard Core Data stack instead.

你可能考虑关闭日志功能,向 NSPersistentStoreCoordinator 添加一个真空选项或切换到标准Core数据堆栈。

You might consider turning Journaling off, adding a vacuum option to your NSPersistentStoreCoordinator or switch to a standard Core Data stack.

这篇关于CoreData,UIManagedDocument和空持久存储的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆