主队列上的dispatch_async块永远不会被占用 [英] dispatch_async block on main queue is never execeuted

查看:91
本文介绍了主队列上的dispatch_async块永远不会被占用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have an app that uses a connection queue that handles the connections on a background thread. Each connection sends a JSON post, then when it receives a success, saves some objects into coredata.

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

Once all connections are complete, i call a dispatch_async on the main thread to call a finished method.

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

However, under very specific conditions of data im sending/saving, I've noticed the dispatch_async block to the main thread never gets called, and the app screen freezes, all execution stops, and the app sits idle with a frozen screen. processing power according to xcode is 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
    }
}

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

My suspicion is this problem has something to do with saving the context then merging it. And possibly while that is happening its released in the middle of the merge, causing some weird hang up and the dispatch isn't getting executed. This is just a guess though, and I don't know how to fix it.

任何想法?

谢谢。

推荐答案

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

If the block on the main thread is not executed, then it is because of 1 of 2 reasons.


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

  1. The main thread is blocked; is not processing any events at all. Got a while() loop on the main thread? That'd do it. A lock? There you go.

主线程在外部运行循环中运行一个模态运行循环。在这种情况下,不会处理主事件循环的异步调度 - 主线程。

The main thread is running a modal run loop inside the outer run loop. Asynchronous dispatches to the main event loop -- main thread -- won't be processed in this case.

设置在 dispatch_async()上的断点,看看主线程正在做什么(在发送时,主线程很可能已经处于坏状态)。

Set a breakpoint on that dispatch_async() and see what the main thread is doing (at the point of dispatch the main thread is most likely already in the bad state).

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

DarkDust's suggestion of using dispatch_after() is a good one, but is unlikely to work in that it is almost assuredly the case that your main thread is not processing events when the problem occurs. I.e. fix the problem, then move to dispatch_after() as DarkDust suggests.

这篇关于主队列上的dispatch_async块永远不会被占用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆