牛骨文教育服务平台(让学习变的简单)
博文笔记

CoreData的多线程存储(代码)

创建时间:2016-06-17 投稿人: 浏览次数:559
上次分享了一篇关于CoreData多线程使用的文章,这次直接上代码。Talk is cheap, show me the code!
1.首先初始化CoreData数据库
// 加载模型文件     NSManagedObjectModel *model = [NSManagedObjectModel mergedModelFromBundles:nil];     // 初始化NSPersistentStoreCoordinator     if (self.PSC == nil) {         self.PSC = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:model];         // SQLite数据库路径         NSString *docs = [NSSearchPathForDirectoriesInDomains(NSCachesDirectory,NSUserDomainMask,YES) lastObject];
        NSURL *url = [NSURL fileURLWithPath:[docs stringByAppendingPathComponent:@"cacheData.sqlite"]];
        NSLog(@"数据库地址:%@", url);
        // 添加持久化存储库,这里使用SQLite作为存储库
        NSError *error = nil;
        NSPersistentStore *store = [self.PSC addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:url options:nil error:&error];
        if (store == nil) { // 直接抛异常
            [NSException raise:@"添加数据库错误" format:@"%@", [error localizedDescription]];
        }     }     // 初始化上下文,设置persistentStoreCoordinator属性。注意:这个是后台存储的上下文     if (self.backgroundWriteContext == nil) {
        NSManagedObjectContext * bgContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
        bgContext.persistentStoreCoordinator = self.PSC;
        self.backgroundWriteContext = bgContext;
    }          // 初始化上下文,设置父级上下文。注意:这个是主线程更新数据的上下文     if (self.context == nil) {
        NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
        self.context = context;
        [self.context setParentContext:self.backgroundWriteContext];     }
2.现在来看存储方法 /**
 *  存入用户信息数据
 *
 *  @param dict 用户信息字典
 */
- (void)saveUserInfoWithDict:(NSDictionary *)totalDict
{
    NSArray * allkeyArray = [totalDict allKeys];
    for (NSString * key in allkeyArray) {
        NSDictionary * dict = totalDict[key];
       
        UserInfoCache * userInfo = [NSEntityDescription insertNewObjectForEntityForName:@"UserInfoCache" inManagedObjectContext:self.context];
       
        if (![dict[@"uid"] isEqual:[NSNull null]]) {
            userInfo.uid = dict[@"uid"];         }     }
   
    NSError *error = nil;
    BOOL success = [self.context save:&error];
    if (!success) {
        [NSException raise:@"访问数据库错误" format:@"%@", [error localizedDescription]];
    }else
    {
        [self.backgroundWriteContext performBlock:^{
            NSError * error1 = nil;
            if (![self.backgroundWriteContext save:&error1]) {
                [NSException raise:@"访问数据库错误" format:@"%@", [error1 localizedDescription]];
            }else
            {
                YJLog(@"成功存储数据到数据库1");
            }
        }];
    } }
代码解读:第一次存储BOOL success = [self.context save:&error];是在主线程存储的,因为这里的数据是和主线程界面绑定的。现在数据其实并没有真正存储到数据库,需要第二次存储后,才真正的存储进CoreData中。 第二次存储: [self.backgroundWriteContext performBlock:^{             NSError * error1 = nil;
            if (![self.backgroundWriteContext save:&error1]) {
                [NSException raise:@"访问数据库错误" format:@"%@", [error1 localizedDescription]];
            }else
            {
                YJLog(@"成功存储数据到数据库1");
            }         }]; 注意这里使用了performBlock,这个上下文的保存就会在异步线程里执行了。这次调用[self.backgroundWriteContext save:&error1],数据就在异步线程里真正的持久化到数据库中了。从前面的初始化方法中也能看出来,bgContext.persistentStoreCoordinator = self.PSC; backgroundWriteContext才真正的关联了持久化对象,而self.context是设置了backgroundWriteContext为他的父级上下文。 注意:这只是异步线程存储一条新数据的方法。查询方法和这个写法不一样,后续会单独写一篇笔记来记录。或者请查看先前分享的文章:CoreData 多线程使用方法 验证方法:大批量存储数据的时候,单纯使用context save会明显感觉主线程卡住,使用此方法实现,卡顿问题基本解决。
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。