iOS学习笔记iOS进阶指南

关于coredata的一些总结

2016-09-02  本文已影响0人  无边小猪

CoreData的构成:
(1)NSManagedObjectContext 被管理者对象上下文,相当于一个未存储的临时数据库,我们存储或者查询都是通过这个对象来的。
(2)NSManagedObjectModel 被管理对象模型,可以简单的理解为可视化建模文件,可视化建模中是Entity自动生成model 方便让文件存储助理来进行管理。
(3)NSPersistentStoreCoordinator 文件存储助理,相当于数据库的链接器,它是CpreData的核心负责链接所有的模块,包括真实的存储文件。
(4)NSManagedObject 被管理的数据记录, 相当于数据库中的表格记录。
(5)NSFetchRequest 获取数据的请求,相当于SQL语句。
(6)NSEntityDescription 实体结构,相当于表结构。
(7)后缀为.xcdatamodeld的包 里面是.xcodemodel文件 用数据模型编辑器编译。编译后为.momd或.mom文件。

一些细节:
1、NSManagedObjectContext创建时apple推荐使用参数NSPrivateQueueConcurrencyType或NSMainQueueConcurrencyType,二者区别如下:

使用NSMainQueueConcurrencyType初始化时,block将会在主线程中执行


[_context performBlock:^(){
    
    [_context save:nil];
    
}];

使用NSPrivateQueueConcurrencyType初始化时,block将会在新子线程中执行,此中情况下涉及到更新UI的操作需要在主线程中调用,因此可以改进如下:

[_context performBlock:^(){
    
    [_context save:nil];
    
    dispatch_async(dispatch_get_main_queue(), ^{
        
        [_tableView reloadData];
        
        [self scrollToBottom];
        
    });
    
}];

2、MOC不是线程安全的,多个线程不能使用同一个,因此多线程使用MOC可以使用parent-child方法解决,每个子线程有一个MOC,主线程有一个MOC,主线程MOC是子线程MOC的parentContext。

例子如下:


 dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^(){
        NSManagedObjectContext *childcontext = [[NSManagedObjectContext alloc]initWithConcurrencyType:NSPrivateQueueConcurrencyType];
        childcontext.parentContext = _context;
        [childcontext performBlock:^(){
            Person *person = [NSEntityDescription insertNewObjectForEntityForName:@"Person" inManagedObjectContext:childcontext];
            person.name = [NSString stringWithFormat:@"json%i",count++];
            person.age = [NSNumber numberWithUnsignedInt:20];
            person.timestamp = [NSDate date];
            NSManagedObjectID *personid = person.objectID;
            [childcontext save:nil];
            [_context performBlock:^(){
                [_context save:nil];
                [_contextWrite performBlockAndWait:^(){
                    if ([_contextWrite hasChanges])
                    {
                        [_contextWrite save:nil];
                    }
                }];
                dispatch_async(dispatch_get_main_queue(), ^(){
                    [self.dataList addObject:[_contextWrite objectWithID:personid]];
                    [_tableView reloadData];
                    [self scrollToBottom];
                });
            }];
        }];
    });

以上parentcontext(main)<---childcontext(private)结构就可以解决大多数问题了,因为数据库的复杂操作往往来自于查询,尤其那些正则匹配、模糊查找,而将这些费时的操作放入childcontext中有多线程异步处理,可以不阻塞主线程。

上面的结构相当于将写入数据库的操作放在主线程中执行,因此对于大量写入数据库的情况是不适用的。而此时则可以使用三层结构解决:grandcontext(private)<---parentcontext(main)<---childcontext(private),其中childcontext负责数据处理查询,parentcontext用于同步操作、解决线程安全问题,grandcontext则用于写入操作。

3、多线程之间是不允许传递NSManagedObject的,但是可以通过传递NSManagedObjectID来解决。

上一篇 下一篇

猜你喜欢

热点阅读