主队列上的dispatch_async块永远不会被占用

我有一个应用程序,它使用连接队列来处理后台线程上的连接。 每个连接发送一个JSONpost,然后当它收到成功时,将一些对象保存到coredata中。

一旦所有连接完成,我在主线程上调用dispatch_async来调用已finished方法。

但是,在非常特定的数据发送/保存条件下,我注意到主线程的dispatch_async块永远不会被调用,应用程序屏幕冻结,所有执行停止,应用程序处于空闲状态并冻结屏幕。 根据xcode的处理能力为0%。

这是块失败的方法。

 - (void)connectionDidComplete { _completeConnections++; _syncProgress = (float)_completeConnections / (float)_totalConnections; dispatch_async(mainQueue, ^(void) { [[NSNotificationCenter defaultCenter] postNotificationName:SyncQueueDidUpdateNotification object:nil]; });  0) { for (SyncObject *syncObject in syncedObjects) { [syncObject delete]; } } //this method saves the current context, then merges this context with the main context right after [[VS_CoreDataManager sharedManager] saveManagedObjectContextAndWait:managedObjectContext]; // cleanup the thread's context [[VS_CoreDataManager sharedManager] unRegisterManagedObjectContextForThread:currentThread]; managedObjectContext = nil; // complete sync dispatch_async(mainQueue, ^(void) { [self performSelector:@selector(finishSync) withObject:nil afterDelay:2]; }); <-- this dispatch never gets called } } 

我怀疑这个问题与保存上下文然后合并它有关。 并且可能正在发生它在合并过程中发布,导致一些奇怪的挂起并且调度没有被执行。 这只是一个猜测,我不知道如何解决它。

有任何想法吗?

谢谢。

如果主线程上的块没有被执行,那么这是由于2个原因之一。

  1. 主线被阻塞; 根本不处理任何事件。 在主线程上有一个while()循环? 那就是它。 锁? 你去吧

  2. 主线程在外部运行循环内运行模态运行循环。 在这种情况下,不会处理异步调度到主事件循环 – 主线程。

dispatch_async()上设置一个断点,看看主线程正在做什么(在调度点,主线程很可能已经处于坏状态)。

DarkDust建议使用dispatch_after()是一个很好的建议,但不太可能有效,因为几乎可以肯定的是,当问题发生时你的主线程没有处理事件。 即解决问题,然后像DarkDust建议的那样转移到dispatch_after()

我相信这是一次很好的讨论。 当我有以下代码时,我遇到了这个:

  dispatch_synch(dispatch_get_main_queue()){ print("I am here") } 

打印代码没有执行,因为我在串行主线程上调度了一个导致死锁的’synch’块。 打印正在等待发送完成并且发送正在等待打印完成。 当您在主串行队列中调度时,您应该使用dispatch_async。 我想如果你使用并发队列,那么调度同步更适合

如果您的主线程忙于模态运行循环,那么您可以尝试

 CFRunLoopPerformBlock(CFRunLoopGetMain(), kCFRunLoopCommonModes, block });