關(guān)于coredata的一些總結(jié)

CoreData的構(gòu)成:
(1)NSManagedObjectContext 被管理者對(duì)象上下文,相當(dāng)于一個(gè)未存儲(chǔ)的臨時(shí)數(shù)據(jù)庫(kù),我們存儲(chǔ)或者查詢都是通過(guò)這個(gè)對(duì)象來(lái)的。
(2)NSManagedObjectModel 被管理對(duì)象模型,可以簡(jiǎn)單的理解為可視化建模文件,可視化建模中是Entity自動(dòng)生成model 方便讓文件存儲(chǔ)助理來(lái)進(jìn)行管理。
(3)NSPersistentStoreCoordinator 文件存儲(chǔ)助理,相當(dāng)于數(shù)據(jù)庫(kù)的鏈接器,它是CpreData的核心負(fù)責(zé)鏈接所有的模塊,包括真實(shí)的存儲(chǔ)文件。
(4)NSManagedObject 被管理的數(shù)據(jù)記錄, 相當(dāng)于數(shù)據(jù)庫(kù)中的表格記錄。
(5)NSFetchRequest 獲取數(shù)據(jù)的請(qǐng)求,相當(dāng)于SQL語(yǔ)句。
(6)NSEntityDescription 實(shí)體結(jié)構(gòu),相當(dāng)于表結(jié)構(gòu)。
(7)后綴為.xcdatamodeld的包 里面是.xcodemodel文件 用數(shù)據(jù)模型編輯器編譯。編譯后為.momd或.mom文件。

一些細(xì)節(jié):
1、NSManagedObjectContext創(chuàng)建時(shí)apple推薦使用參數(shù)NSPrivateQueueConcurrencyType或NSMainQueueConcurrencyType,二者區(qū)別如下:

使用NSMainQueueConcurrencyType初始化時(shí),block將會(huì)在主線程中執(zhí)行


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

使用NSPrivateQueueConcurrencyType初始化時(shí),block將會(huì)在新子線程中執(zhí)行,此中情況下涉及到更新UI的操作需要在主線程中調(diào)用,因此可以改進(jìn)如下:

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

2、MOC不是線程安全的,多個(gè)線程不能使用同一個(gè),因此多線程使用MOC可以使用parent-child方法解決,每個(gè)子線程有一個(gè)MOC,主線程有一個(gè)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)結(jié)構(gòu)就可以解決大多數(shù)問(wèn)題了,因?yàn)閿?shù)據(jù)庫(kù)的復(fù)雜操作往往來(lái)自于查詢,尤其那些正則匹配、模糊查找,而將這些費(fèi)時(shí)的操作放入childcontext中有多線程異步處理,可以不阻塞主線程。

上面的結(jié)構(gòu)相當(dāng)于將寫(xiě)入數(shù)據(jù)庫(kù)的操作放在主線程中執(zhí)行,因此對(duì)于大量寫(xiě)入數(shù)據(jù)庫(kù)的情況是不適用的。而此時(shí)則可以使用三層結(jié)構(gòu)解決:grandcontext(private)<---parentcontext(main)<---childcontext(private),其中childcontext負(fù)責(zé)數(shù)據(jù)處理查詢,parentcontext用于同步操作、解決線程安全問(wèn)題,grandcontext則用于寫(xiě)入操作。

3、多線程之間是不允許傳遞NSManagedObject的,但是可以通過(guò)傳遞NSManagedObjectID來(lái)解決。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容