CoreData NSSQLiteStoreType没有获取关系

时间:2015-01-15 08:18:01

标签: ios core-data ios8

在我的应用程序中,我使用的是Core Data,存储类型为NSSQLiteStoreType。启动ios 8 sdk所有对象的关系都不从Core Data获取。任何人都可以解释ios 8中Core Data的不同之处,我该如何解决这个问题呢?

以下是我的DataService代码:

-(id)init{
    self = [super init];
    if (self){
        coreDataHelpersForDispatchQueues = [NSMutableDictionary dictionary];
        contextsForQispatchQueues = [NSMutableDictionary dictionary];

        _managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:[[NSBundle mainBundle] URLForResource:@"Name" withExtension:@"momd"]];

        _persistentStoreCoordinator = [self createStoreCoordinatorWithDataModel:_managedObjectModel storeUrl:[NSURL fileURLWithPath:[self databaseLocationPath:@"Name.sqlite"]]];

        self.coreDataHelper = self.coreDataHelperForCurrentDispatchQueue;
        _managedObjectContext = self.coreDataHelper.moc;
        _managedObjectContext.mergePolicy = NSOverwriteMergePolicy;
        [self logCount];

    }
    return self;
}

-(void)logCount{
    @synchronized(coreDataHelpersForDispatchQueues){
        //NSLog(@"count|%d|",coreDataHelpersForDispatchQueues.count);
    }
    [self performSelector:@selector(logCount) withObject:nil afterDelay:1];
}


#pragma mark - currentCDH

-(CoreDataHelper*)coreDataHelperForCurrentDispatchQueue{
    @synchronized(coreDataHelpersForDispatchQueues){
        CoreDataHelper* helper = coreDataHelpersForDispatchQueues[dispatch_current_queue_id];
        if (!helper){
            helper = [[CoreDataHelper alloc] initWithContext:self.newManagedObjectContext];
            helper.retainCounter = 1;
            coreDataHelpersForDispatchQueues[dispatch_current_queue_id] = helper;
            NSLog(@"new helper|%@| context|%@| queue|%s|",helper,helper.moc,dispatch_queue_get_label(dispatch_get_current_queue()));
        }
        return helper;
    }
}

-(void)retainCoreDataHelper:(CoreDataHelper*)coreDataHelper_{
    coreDataHelper_.retainCounter ++;
}

-(void)releaseCoreDataHelper:(CoreDataHelper *)coreDataHelper_ now:(BOOL)now_{
    if (!coreDataHelper_ || (coreDataHelper_.moc == self.coreDataHelper.moc && !now_))
        return;

    coreDataHelper_.retainCounter --;
    if (now_ || coreDataHelper_.retainCounter <= 0){
        __block CoreDataHelper* helper = coreDataHelper_;

        dispatch_block_t doit = ^{
            NSLog(@"consuming helper|%@| context|%@| started",helper,helper.moc);
            [[NSNotificationCenter defaultCenter] removeObserver:self name:NSManagedObjectContextDidSaveNotification object:helper.moc];

            @synchronized(contextsForQispatchQueues){
                NSNumber* keyToRemove = nil;
                for (NSNumber* key in contextsForQispatchQueues) {
                    if (contextsForQispatchQueues[key] == helper.moc){
                        keyToRemove = key;
                        break;
                    }
                }
                if (keyToRemove)
                    [contextsForQispatchQueues removeObjectForKey:keyToRemove];
            }

            @synchronized(coreDataHelpersForDispatchQueues){
                NSNumber* keyToRemove = nil;
                for (NSNumber* key in coreDataHelpersForDispatchQueues) {
                    if (coreDataHelpersForDispatchQueues[key] == coreDataHelper_){
                        keyToRemove = key;
                        break;
                    }
                }
                if (keyToRemove)
                    [coreDataHelpersForDispatchQueues removeObjectForKey:keyToRemove];
            }
            NSLog(@"consuming helper|%@| context|%@| finished",helper,helper.moc);
        };

        if (now_){
            NSLog(@"will consume helper|%@| context|%@| queue|%s| just now",helper,helper.moc,dispatch_queue_get_label(dispatch_get_current_queue()));
            doit();
        }else{
            int64_t delayInSeconds = 5.0;
            NSLog(@"will consume helper|%@| context|%@| queue|%s| in %lld seconds",helper,helper.moc,dispatch_queue_get_label(dispatch_get_current_queue()),delayInSeconds);
            dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, delayInSeconds * NSEC_PER_SEC);
            dispatch_after(popTime, dispatch_get_global_queue(0, 0), doit);
        }
    }
}

-(NSManagedObjectContext*)newManagedObjectContext{
    NSManagedObjectContext* context = [[NSManagedObjectContext alloc] init];
    context.persistentStoreCoordinator = self.persistentStoreCoordinator;
    @synchronized(contextsForQispatchQueues){
        contextsForQispatchQueues[dispatch_current_queue_id] = context;
    }
    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleContextDidSaveNotification:) name: NSManagedObjectContextDidSaveNotification object:context];
    return context;
}

-(void)handleContextDidSaveNotification:(NSNotification *)notification {
    @synchronized(contextsForQispatchQueues){
        NSManagedObjectContext* savedContext = notification.object;
        for (NSManagedObjectContext* context in contextsForQispatchQueues.allValues) {
            if (context != savedContext)
                [context mergeChangesFromContextDidSaveNotification:notification];
        }
    }
}

#pragma mark -

-(NSPersistentStoreCoordinator*)createStoreCoordinatorWithDataModel:(NSManagedObjectModel*)model storeUrl:(NSURL*)url{
    NSError *error = nil;
    NSPersistentStoreCoordinator* cordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];

    NSDictionary *options = @{
                              NSSQLitePragmasOption: @{@"journal_mode": @"OFF"}
                              };

    if (![cordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:options error:&error]){
        [[NSFileManager defaultManager] removeItemAtURL:url error:nil];
        NSLog(@"database was purged: %@",url.absoluteString);
        NSError* error2 = nil;
        if (![cordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:options error:&error2]) {
            NSLog(@"Unresolved error %@, %@", error2, [error2 userInfo]);
            abort();
        }
    }
    return cordinator;
}

-(NSManagedObjectContext*)createManagedObjectContextForStoreCoordinator:(NSPersistentStoreCoordinator*)coordinator{
    NSManagedObjectContext* context = [[NSManagedObjectContext alloc] init];
    context.persistentStoreCoordinator = coordinator;

//    [[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(handleContextSavedNotification:) name:NSManagedObjectContextDidSaveNotification object:context];
    return context;
}

#pragma mark - Core Data stack


-(NSString*)databaseLocationPath:(NSString*)databaseName{

    NSArray* documentDirectoryFolderLocation = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
    return [[documentDirectoryFolderLocation objectAtIndex:0] stringByAppendingPathComponent:databaseName];
}

更新

以下是我获取结果的代码:

 NSFetchRequest* oldInstructionsRequest = [[NSFetchRequest alloc] initWithEntityName:@"Instruction"];
                    oldInstructionsRequest.predicate = [NSPredicate predicateWithFormat:@"isFromList == NO && isForUpload == NO"];
                    oldInstructions = [app.dataService.managedObjectContextCopy executeFetchRequest:oldInstructionsRequest error:nil];

<Instruction: 0x190fae40> (entity: Instruction; id: 0x190fa7b0 <x-coredata://BDC5225D-BD51-412B-A247-C0A66947EA74/Instruction/p1> ; data: {
    author = Public;
    color = "";
    created = "2014-02-28 10:21:50 +0000";
    estimation = 0;
    evaluation = nil;
    favourite = 0;
    id = "100b1974-0cdd-4d94-a34f-caf3e2c0cc08";
    imageId = 1955;
    isForUpdate = 0;
    isForUpload = 0;
    isFromList = 1;
    isNew = 0;
    isRemoved = 0;
    modified = "2014-04-18 16:33:55 +0000";
    name = "Types of steps";
    state = 4;
    steps = "<relationship fault: 0x17f45ab0 'steps'>";
}),

1 个答案:

答案 0 :(得分:1)

您的核心数据并发方法(使用调度队列)并不能保证能够正常工作。您只能从单个线程访问NSManagedObjectContext中的对象,但可以在不同的线程上执行在调度队列上调度的块。

使用performBlock:中的performBlockAndWait:NSManagedObjectContext方法。如果你这样做,你根本不需要@synchronized个陈述。