具有多个并行数据库访问的iOS应用程序设计
在我的应用程序中,我获取带有JSON内容的请求,解析它们并将它们存储在CoreData中。同时,用户与数据库交互(读写访问) 将数据存储到数据库后,将启动第二个任务,根据接收到的数据创建新数据。我将使用GrandCentralDispatch进行解析,并将数据存储到数据库中 我的问题是,当使用GCD时,我得到了一个具有多个并行数据库访问的iOS应用程序设计,ios,core-data,grand-central-dispatch,nsmanagedobjectcontext,Ios,Core Data,Grand Central Dispatch,Nsmanagedobjectcontext,在我的应用程序中,我获取带有JSON内容的请求,解析它们并将它们存储在CoreData中。同时,用户与数据库交互(读写访问) 将数据存储到数据库后,将启动第二个任务,根据接收到的数据创建新数据。我将使用GrandCentralDispatch进行解析,并将数据存储到数据库中 我的问题是,当使用GCD时,我得到了一个EXC\u BAD\u ACCESS,这可能是由于我假设的核心数据的非线程安全性造成的。另一个错误是在使用contextperformBlockAndWait时出现死锁 我应该如何设计
EXC\u BAD\u ACCESS
,这可能是由于我假设的核心数据的非线程安全性造成的。另一个错误是在使用contextperformBlockAndWait
时出现死锁
我应该如何设计能够正确处理GCD和NSMutableContexts
的应用程序
-------编辑--------
既然我已经阅读了核心数据编程指南,我就必须使用线程限制模式
我的应用程序目前的结构是这样的:我有几个经理,每个经理都有自己的背景。但是当使用多个线程时,我会发现3个线程调用同一个管理器,这意味着3个线程同时使用一个上下文。这将导致死锁
为了解决这个问题,我想到了通过threadname创建一个上下文,如下所示:
- (NSManagedObjectContext *)createManagedObjectContextWithTreadName:(NSString*) threadname {
if([NSThread currentThread].name.length ==0){
[NSThread currentThread].name = threadname;
}
NSManagedObjectContext *context = nil;
context = [self.contextStore objectForKey:threadname];
if(!context){
NSLog(@"Creating context for threadname: %@",threadname);
NSPersistentStoreCoordinator *coordinator = self.persistentStoreCoordinator;
if (coordinator != nil)
{
context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
context.persistentStoreCoordinator = coordinator;
context.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy;
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self selector:@selector(mergeChangesFromMOC:) name:NSManagedObjectContextDidSaveNotification object:context];
[self.contextStore setValue:context forKey:threadname];
}
}
return context;
}
这是一个好主意吗?从阅读开始。从阅读开始。好的-以下是我解决问题的方法:
+(NSManagedObjectContext *)managedObjectContext {
AppDelegate *delegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
NSManagedObjectContext *moc = delegate.managedObjectContext;
NSThread *thread = [NSThread currentThread];
if ([thread isMainThread]) {
return moc;
}
// a key to cache the context for the given thread
NSString *threadKey = [NSString stringWithFormat:@"%p", thread];
// delegate.managedObjectContexts is a mutable dictionary in the app delegate
NSMutableDictionary *managedObjectContexts = delegate.managedObjectContexts;
if ( [managedObjectContexts objectForKey:threadKey] == nil ) {
// create a context for this thread
NSManagedObjectContext *threadContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
threadContext.persistentStoreCoordinator = [moc persistentStoreCoordinator];
threadContext.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy;
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self selector:@selector(mergeChangesFromMOC:) name:NSManagedObjectContextDidSaveNotification object:threadContext];
// cache the context for this thread
[managedObjectContexts setObject:threadContext forKey:threadKey];
//NSLog(@"MocCount: %d",managedObjectContexts.count);
}
return [managedObjectContexts objectForKey:threadKey];
}
+ (void)mergeChangesFromMOC:(NSNotification *)aNotification {
//NSLog(@"Performing a merge of managed object context in class %@",[self class]);
@try {
AppDelegate *delegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
NSManagedObjectContext *moc = delegate.managedObjectContext;
[moc mergeChangesFromContextDidSaveNotification:aNotification];
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc removeObserver:self name:NSManagedObjectContextDidSaveNotification object:[aNotification object]];
}
@catch (NSException * e) {
NSLog(@"Stopping on exception: %@", [e description]);
}
@finally {}
}
在任何需要上下文的地方,我都会询问[ContainingClass managedObjectContext],并获取主线程或我所在线程的上下文。当需要合并时,这将在主线程上执行。确定-以下是我如何解决它的:
+(NSManagedObjectContext *)managedObjectContext {
AppDelegate *delegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
NSManagedObjectContext *moc = delegate.managedObjectContext;
NSThread *thread = [NSThread currentThread];
if ([thread isMainThread]) {
return moc;
}
// a key to cache the context for the given thread
NSString *threadKey = [NSString stringWithFormat:@"%p", thread];
// delegate.managedObjectContexts is a mutable dictionary in the app delegate
NSMutableDictionary *managedObjectContexts = delegate.managedObjectContexts;
if ( [managedObjectContexts objectForKey:threadKey] == nil ) {
// create a context for this thread
NSManagedObjectContext *threadContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
threadContext.persistentStoreCoordinator = [moc persistentStoreCoordinator];
threadContext.mergePolicy = NSMergeByPropertyStoreTrumpMergePolicy;
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc addObserver:self selector:@selector(mergeChangesFromMOC:) name:NSManagedObjectContextDidSaveNotification object:threadContext];
// cache the context for this thread
[managedObjectContexts setObject:threadContext forKey:threadKey];
//NSLog(@"MocCount: %d",managedObjectContexts.count);
}
return [managedObjectContexts objectForKey:threadKey];
}
+ (void)mergeChangesFromMOC:(NSNotification *)aNotification {
//NSLog(@"Performing a merge of managed object context in class %@",[self class]);
@try {
AppDelegate *delegate = (AppDelegate*)[UIApplication sharedApplication].delegate;
NSManagedObjectContext *moc = delegate.managedObjectContext;
[moc mergeChangesFromContextDidSaveNotification:aNotification];
NSNotificationCenter *nc = [NSNotificationCenter defaultCenter];
[nc removeObserver:self name:NSManagedObjectContextDidSaveNotification object:[aNotification object]];
}
@catch (NSException * e) {
NSLog(@"Stopping on exception: %@", [e description]);
}
@finally {}
}
在任何需要上下文的地方,我都会询问[ContainingClass managedObjectContext],并获取主线程或我所在线程的上下文。当需要合并时,这将在主线程上执行。只是一个问题,如何删除不再活动的线程的上下文?只是一个问题,如何删除不再活动的线程的上下文?