CoreData的多线程存储(代码)
上次分享了一篇关于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会明显感觉主线程卡住,使用此方法实现,卡顿问题基本解决。
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会明显感觉主线程卡住,使用此方法实现,卡顿问题基本解决。
声明:该文观点仅代表作者本人,牛骨文系教育信息发布平台,牛骨文仅提供信息存储空间服务。
- 上一篇: iOS CoreData简介及使用中的注意点
- 下一篇: TP5添加内容