【发布时间】:2014-09-16 07:43:18
【问题描述】:
我在核心数据中有一个父-子-孙核心数据上下文设置,如下所示。每当我尝试在孙上下文上执行获取请求时,都会导致线程死锁
- (NSManagedObjectContext *)defaultPrivateQueueContext
{
if (!_defaultPrivateQueueContext) {
_defaultPrivateQueueContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
_defaultPrivateQueueContext.persistentStoreCoordinator = self.persistentStoreCoordinator;
}
return _defaultPrivateQueueContext;
}
- (NSManagedObjectContext *)mainThreadContext {
if (!_mainThreadContext) {
_mainThreadContext = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSMainQueueConcurrencyType];
_mainThreadContext.parentContext = [self defaultPrivateQueueContext];
}
return _mainThreadContext;
}
+ (NSManagedObjectContext *)newPrivateQueueContext
{
NSManagedObjectContext *context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
context.parentContext = [[self sharedParliamentAPI] mainThreadContext];
return context;
}
这是我的代码,它会导致死锁(尝试执行获取请求时):
- (void)fetchMenuItemsWithCompletion:(void (^) (BOOL success, NSString *message))completionBlock {
NSMutableURLRequest *request = [APIHelper createNewRequestWithURLExtension:@"menuitems" httpMethodType:@"GET" parameters:nil];
NSURLSession *session = [NSURLSession sessionWithConfiguration:self.sessionConfig];
NSURLSessionDataTask *dataTask = [session dataTaskWithRequest:request completionHandler:^(NSData *data, NSURLResponse *response, NSError *error) {
NSObject *json = [NSJSONSerialization JSONObjectWithData:data options:0 error:nil];
if ([[json valueForKey:@"isSuccess"] boolValue]) {
NSManagedObjectContext *defaultContext = self.defaultPrivateQueueContext;
NSManagedObjectContext *privateQueueContext = [ParliamentAPI newPrivateQueueContext];
[privateQueueContext performBlock:^{
__block NSError *error;
NSFetchRequest *request = [NSFetchRequest fetchRequestWithEntityName:@"MenuItem"];
NSArray *fetchedRecords = [privateQueueContext executeFetchRequest:request error:&error];
// do stuff with fetchedRecords
}];
} else {
completionBlock([[json valueForKey:@"isSuccess"] boolValue], [json valueForKey:@"message"]);
}
}];
[dataTask resume];
}
【问题讨论】:
-
mainThreadContext有什么用? everything 是否通过 performBlock 或 performBlockAndWait 使用该上下文?如果没有,那可能会导致孩子陷入僵局。 -
在执行此代码时,未使用 mainThreadContext。是的,所有使用该上下文的东西都是通过 performBLock
-
如果将根上下文设置为新子上下文的父级,消除主线程上下文,是否还死锁?
-
当我将新子上下文的父级设置为根上下文时,死锁消失了。但是,这样做不会在进行更改时更新 mainThreadContext(因为它是根上下文的单独子项)
标签: core-data concurrency deadlock nsmanagedobjectcontext