我正在尝试实现获取请求,但它似乎处于死锁状态。
> Thread 1, Queue : com.apple.main-thread
> #0 0x38329fa8 in __psynch_mutexwait ()
> #1 0x38390f0e in _pthread_mutex_lock ()
> #2 0x2d3aaad0 in -[_PFLock lock] ()
> #3 0x2d3bbba4 in -[NSPersistentStoreCoordinator executeRequest:withContext:error:] ()
> #4 0x2d3ba7e6 in -[NSManagedObjectContext executeFetchRequest:error:] ()
> #5 0x2d448bb6 in -[NSManagedObjectContext(_NestedContextSupport) _parentObjectsForFetchRequest:inContext:error:] ()
> #6 0x2d44932e in __82-[NSManagedObjectContext(_NestedContextSupport) executeRequest:withContext:error:]_block_invoke ()
> #7 0x2d43ec82 in _perform ()
> #8 0x2d449030 in -[NSManagedObjectContext(_NestedContextSupport) executeRequest:withContext:error:] ()
> #9 0x2d3ba7e6 in -[NSManagedObjectContext executeFetchRequest:error:] ()
> #10 0x000e4c90 in +[PhotoDAO getNotSentPhotos:] at /Users/vitrinysolutions/Documents/Workspace XCode/Novo
> SmileClick/SmileClick/SmileClick/DAOs/PhotoDAO.m:236
> #11 0x0009f210 in -[EventManager loadQueue:] at /Users/vitrinysolutions/Documents/Workspace XCode/Novo
> SmileClick/SmileClick/SmileClick/Util/EventManager.m:59
> #12 0x00095fb0 in -[EventMainViewController viewDidAppear:] at /Users/vitrinysolutions/Documents/Workspace XCode/Novo
> SmileClick/SmileClick/SmileClick/ViewControllers/EventMainViewController.m:60
> #13 0x2fdf03da in -[UIViewController _setViewAppearState:isAnimating:] ()
> #14 0x2fdf085c in -[UIViewController _endAppearanceTransition:] ()
> #15 0x2fe9ced2 in -[UINavigationController navigationTransitionView:didEndTransition:fromView:toView:] ()
> #16 0x2ff6831c in __49-[UINavigationController _startCustomTransition:]_block_invoke ()
> #17 0x2feecc22 in -[_UIViewControllerTransitionContext completeTransition:] ()
> #18 0x2ffacff6 in __53-[_UINavigationParallaxTransition animateTransition:]_block_invoke105 ()
> #19 0x2fe0dfe8 in -[UIViewAnimationBlockDelegate _didEndBlockAnimation:finished:context:] ()
> #20 0x2fe0dc36 in -[UIViewAnimationState sendDelegateAnimationDidStop:finished:] ()
> #21 0x2fe0db4e in -[UIViewAnimationState animationDidStop:finished:] ()
> #22 0x2fa65d08 in CA::Layer::run_animation_callbacks(void*) ()
> #23 0x3824ed66 in _dispatch_client_callout ()
> #24 0x382557c0 in _dispatch_main_queue_callback_4CF$VARIANT$mp ()
> #25 0x2d62f820 in __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__ ()
> #26 0x2d62e0f4 in __CFRunLoopRun ()
> #27 0x2d598ce6 in CFRunLoopRunSpecific ()
> #28 0x2d598aca in CFRunLoopRunInMode ()
> #29 0x32286282 in GSEventRunModal ()
> #30 0x2fe3aa40 in UIApplicationMain ()
> #31 0x000aeedc in main at /Users/vitrinysolutions/Documents/Workspace XCode/Novo SmileClick/SmileClick/SmileClick/main.m:16
我有这些方法来制作我的孩子语境:
static __strong NSManagedObjectContext *context;
+(NSManagedObjectContext*) context {
if (context == nil) {
context = [[NSManagedObjectContext alloc] initWithConcurrencyType:NSPrivateQueueConcurrencyType];
[context setParentContext: [((AppDelegate*)[[UIApplication sharedApplication] delegate]) managedObjectContext]];
}
return context;
}
+ (void)save:(NSManagedObjectContext *)context {
[context performBlockAndWait:^{
NSError *error;
if (![context save:&error]) {
NSLog(@"Child Context Error: %@", error);
} else {
NSManagedObjectContext *parentContext = [((AppDelegate*)[[UIApplication sharedApplication] delegate]) managedObjectContext];
if (![parentContext save:&error]) {
NSLog(@"Parent Context Error: %@", error);
}
}
}];
}
我的获取方法:
+(NSArray *) getNotSentPhotos: (Event *) oEvent {
NSManagedObjectContext *context = [self context];
NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] init];
NSEntityDescription *entity = [NSEntityDescription entityForName:@"Photo" inManagedObjectContext:context];
[fetchRequest setEntity:entity];
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"(event == %@) AND (server_status == %@)", oEvent, SERVER_STATUS_PENDENTE];
[fetchRequest setPredicate:predicate];
NSError *error = nil;
NSArray *fetchedObjects = [context executeFetchRequest:fetchRequest error:&error];
return fetchedObjects;
}
我的子上下文是NSPrivateQueueConcurrencyType,所有保存都是使用performBlock
完成的。
我想做些什么才能让它正常运行?
谢谢。
答案 0 :(得分:3)
你提到“所有保存都是使用performBlock
”完成的,这很好但不够。 NSManagedObjectContext
对于几乎所有事情都不是线程安全的。您的获取请求不在performBlock
的上下文中,但确实需要。此外,您使用上下文的其他所有内容,以及使用您获取的托管对象时。像这样的死锁是线程问题的典型症状,performBlock
旨在帮助避免。
答案 1 :(得分:0)
我发现了问题,我的NSFetchedResultsController
未使用performBlock
的子上下文。
谢谢Tom Harrington。