你好,歡迎來到IOS教程網

 Ios教程網 >> IOS編程開發 >> IOS開發綜合 >> iOS代碼重構(二)CoreData多線程(支持線程平安)

iOS代碼重構(二)CoreData多線程(支持線程平安)

編輯:IOS開發綜合

CoreData對多線程的支持比擬奇異(依照普通的思緒來說),CoreData的NSPersistentStoreCoordinator和NSManagedObjectContext對象都是不能跨線程運用的,NSManagedObject也不行,有人想加鎖不就完了。

前提描繪

原項目中已有CoreData封裝,但是線程不完全的,而且使用的中央較多,參考了網上的一些文章,假如按主流的搞個三層上下文saveMOC,mainMOC,newPrivateMOC,使用Block來完成異步。但項目改動較大。而且經測試,代碼強健性不是很好,多線程操作時,

有解體景象。原項目中的數據庫文件,是按用戶,辨別創立的。

根本方案:使用MagicRecord局部API,完成Core線程平安。

直接上代碼吧

1 初始化操作

AppDelegate.m

NSString *userId = [[PublicObject publicObjectInstance] getUserId];

if (userId) {//登錄後再初始化本地數據庫

[[CoreDataManager shareInstance] setupCoreDataStack];

[MagicalRecord setLoggingLevel:MagicalRecordLoggingLevelAll];

}


2 CoreDataManager局部函數

- (void) setupCoreDataStack

{

if ([NSPersistentStoreCoordinator MR_defaultStoreCoordinator] != nil) return;

NSPersistentStoreCoordinator *coordinator = [self persistentStoreCoordinator];

[NSPersistentStoreCoordinator MR_setDefaultStoreCoordinator:coordinator];

[NSManagedObjectContext MR_initializeDefaultContextWithCoordinator:coordinator];

}


// Returns the managed object model for the application.

// If the model doesn't already exist, it is created from the application's model.

- (NSManagedObjectModel *)managedObjectModel {

if (!_managedObjectModel) {

NSURL *modelURL = [[NSBundle mainBundle] URLForResource:@"ModelObject" withExtension:@"momd"];

_managedObjectModel = [[NSManagedObjectModel alloc] initWithContentsOfURL:modelURL];

}

return _managedObjectModel;

}


// Returns the persistent store coordinator for the application.

// If the coordinator doesn't already exist, it is created and the application's store added to it.

- (NSPersistentStoreCoordinator *)persistentStoreCoordinator {

if (!_persistentStoreCoordinator) {

NSURL* storeURL = [NSURL fileURLWithPath:[FileHelper infodbFilePath]];//Lib目錄/用戶ID/info.db

NSError *error = nil;

_persistentStoreCoordinator = [[NSPersistentStoreCoordinator alloc] initWithManagedObjectModel:[self managedObjectModel]];

NSDictionary *options = @{NSMigratePersistentStoresAutomaticallyOption : [NSNumber numberWithBool:YES],

NSInferMappingModelAutomaticallyOption : [NSNumber numberWithBool:YES]};

if (![_persistentStoreCoordinator addPersistentStoreWithType:NSSQLiteStoreType configuration:nil URL:storeURL options:options error:&error]) {

NSLog(@"Unresolved error %@, %@", error, [error userInfo]);

abort();

}

}

return _persistentStoreCoordinator;

}

-(BOOL) save:(NSError **)error{

[[NSManagedObjectContext MR_defaultContext] MR_saveToPersistentStoreAndWait];

return YES;

}

- (void)removeObjectsWithPredicate:(NSPredicate*)predicate inEntity:(NSString*)entityName {

NSManagedObjectContext *context = [NSManagedObjectContext MR_context];

NSFetchRequest *request = [[NSFetchRequest alloc] init];

request.predicate = predicate;

request.includesPropertyValues = NO;

request.entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:context];

[context performBlockAndWait:^{

NSError *error;

NSArray *objects = [context executeFetchRequest:request error:&error];

if (!error && objects.count) {

for (NSManagedObject *obj in objects) {

[context deleteObject:obj];

}

}

}];

[context MR_saveToPersistentStoreAndWait];

}


- (NSMutableArray*)findObjectsIn:(NSString*)entityName withPredicate:(NSPredicate*)predicate andSortDescriptors:(NSArray*)sortDescriptors andObjectClass:(Class)objClass {

NSManagedObjectContext *context = [NSManagedObjectContext MR_context];

NSFetchRequest *request = [[NSFetchRequest alloc] init];

request.predicate = predicate;

request.sortDescriptors = sortDescriptors;

request.entity = [NSEntityDescription entityForName:entityName inManagedObjectContext:context];

__block NSMutableArray *results = nil;

[context performBlockAndWait:^{

NSError *error = nil;

NSArray *objects = [context executeFetchRequest:request error:&error];

if (objects == nil)

{

NSLog(@"%@",error);

return ;

}

results = [NSMutableArray arrayWithCapacity:objects.count];

if (!error && objects.count) {

for (id entity in objects) {

id obj = [[objClass alloc] initWithEntity:entity];

[results addObject:obj];

}

}

}];

return results;


}

//拔出

- (void)insertProgressAndAttachments:(NSArray *)progressArray

{

NSManagedObjectContext *context = [NSManagedObjectContext MR_context];

for (Progress *progress in progressArray) {

Progress* entity = (Progress*)[NSEntityDescription insertNewObjectForEntityForName:TBProgress

inManagedObjectContext:context];

entity.projectId = progress.projectId;

entity.buildingId = progress.buildingId;

entity.progressId = progress.progressId;

entity.createdDate = progress.createdDate;

entity.createdBy = progress.createdBy;

entity.lastModifiedDate = progress.lastModifiedDate;

entity.lastModifiedBy = progress.lastModifiedBy;

entity.occurredDate = progress.occurredDate;

entity.progressDesc = progress.progressDesc;

entity.version = progress.version;

entity.progressStatus = progress.progressStatus;

entity.conflict = progress.conflict;

entity.weather = progress.weather;

entity.temperature = progress.temperature;

entity.WindPower = progress.WindPower;

for (ProgressAttachment *attach in progress.attachments) {

[self insertProgressAttachment:attach];

}

for (ProgressWorkType *workType in progress.workTypes) {

[self insertProgressWorkType:workType];

}

for (ProgressDelayReason *delayReason in progress.delayReasons) {

[self insertProgressDelayReason:delayReason];

}

}

[context MR_saveToPersistentStoreAndWait];

}

//查找

- (Progress*)findProgressById:(NSString *)progressId {

return [self findFirstObjectIn:TBProgress

withPredicate:[NSPredicate predicateWithFormat:@"progressId = %@", progressId]

andSortDescriptors:nil

andObjectClass:[Progress class]];

}

//刪除

// 刪除一個項目的一切進度附件

- (void)removeAllProgressAttachmentByProject:(NSString*)projectId {

[self removeObjectsWithPredicate:[NSPredicate predicateWithFormat:@"projectId = %@", projectId]

inEntity:TBProgressAttachment];

}


參考文章:

源碼

https://github.com/search?utf8=✓&q=IOS+coredata+thread


原理-知識

看法CoreData—多線程

http://www.tuicool.com/articles/2iimue


IOS開發中一些罕見的並行處置

http://www.cocoachina.com/industry/20131212/7525.html


對應Demo

https://github.com/Acorld/IOS_CoreData_MutThread_Demo


在多線程環境中運用CoreData

http://www.iliunian.com/2896.html


英文版

https://www.coco.netics.com/2012/07/multi-context-coredata/


不再替Core Data多線程編程而頭疼

http://www.myexception.cn/program/1937577.html



Magical Record 片面解析

http://www.jianshu.com/p/590c6db9cdd6


MagicalRecord 初始化,數據遷移與提早預制數據庫邏輯

http://www.jianshu.com/p/cd1a06c7ce09



【iOS代碼重構(二)CoreData多線程(支持線程平安)】的相關資料介紹到這裡,希望對您有所幫助! 提示:不會對讀者因本文所帶來的任何損失負責。如果您支持就請把本站添加至收藏夾哦!

  1. 上一頁:
  2. 下一頁:
蘋果刷機越獄教程| IOS教程問題解答| IOS技巧綜合| IOS7技巧| IOS8教程
Copyright © Ios教程網 All Rights Reserved