我有一个应用程序,它使用连接队列来处理后台线程上的连接。每个连接发送一个JSON帖子,然后当它收到成功时,将一些对象保存到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];
}); <-- this dispatch works
if (_completeConnections == _totalConnections)
{
// clear unsynced data
NSArray *syncedObjects = [SyncObject completedSyncObjects];
if (syncedObjects.count > 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
}
}
我怀疑这个问题与保存上下文然后合并它有关。并且可能正在发生它在合并过程中发布,导致一些奇怪的挂断并且调度没有被执行。这只是一个猜测,我不知道如何解决它。
有什么想法吗?
感谢。
答案 0 :(得分:23)
如果主线程上的块没有被执行,则是由于2个原因之一。
主线被阻止;根本不处理任何事件。在主线程上有一个while()循环?那就做了。锁?你去吧。
主线程在外部运行循环内运行模态运行循环。主要事件循环的异步调度 - 主线程 - 在这种情况下不会被处理。
在dispatch_async()
上设置一个断点,看看主线程在做什么(在发送时,主线程很可能已经处于坏状态)。
DarkDust使用dispatch_after()
的建议是一个很好的建议,但不太可能有效,因为几乎可以确定你的主线程在问题发生时没有处理事件。即解决问题,然后按照DarkDust的建议移至dispatch_after()
。
答案 1 :(得分:0)
我相信这是一次很棒的讨论。当我有以下代码时,我遇到了这个:
dispatch_synch(dispatch_get_main_queue()){
print("I am here")
}
打印代码没有执行,因为我在串行主线程上调度了一个导致死锁的'synch'块。打印等待发送完成,发送等待打印完成。当您在主串行队列中调度时,您应该使用dispatch_async。我想如果你使用并发队列,那么调度同步更适合
答案 2 :(得分:-1)
如果您的主线程忙于模态运行循环,那么您可以尝试
CFRunLoopPerformBlock(CFRunLoopGetMain(), kCFRunLoopCommonModes, block
});