CoreData,UIManagedDocument和空Persistent Store

时间:2014-01-24 15:30:26

标签: ios objective-c core-data uimanageddocument

我正在使用UIManagedDocument来阅读和写入CoreData。我有Document课。这是一些教程中的文档:

·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];
}

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行。为什么?

2 个答案:

答案 0 :(得分:3)

第二次启动应用时会发生什么,您能否在应用中看到数据?

在iOS 7中,SQLite现在启用了日记功能。我想知道日志是否会引起混淆(数据存在,但在sqlite文件中却没有)。

我还会质疑你使用UIManagedDocument的原因。看来你正在以单例模式使用核心数据(这很糟糕),然后在该单例模式中使用UIManagedDocument(更糟糕)。

UIManagedDocument适用于基于文档的应用。如果您构建了标准的Core Data堆栈,那么您可能会对该类中的某些“自动”功能进行犯规,这些功能很容易被清除。

您可以考虑关闭日记功能,为NSPersistentStoreCoordinator添加真空选项或切换到标准核心数据堆栈。

答案 1 :(得分:0)

这可能是因为iOS 7中使用了新的SQLite日记帐模式。如果您将其设置为旧模式,如以下SO问题的答案所示,您应该再次看到您的数据。

How to disable WAL journal mode