2

我有一个经常和永久冻结的应用程序。发生这种情况时,我在 Xcode 中单击暂停,并看到在主线程上它总是停在执行 MOC 上的获取请求的代码行处。我还在__psynch_mutexwait + 17左侧的线程列表中看到了输出。这让我假设应用程序遇到死锁或由于某种原因 MOC 被阻止。

我的第一直觉是,我可能正在非主线程上执行 fetch 请求,所以我放入日志进行检查,但事实并非如此。所有获取都发生在主线程上。

我怎样才能去追踪可能在这里阻塞的东西?我应该在堆栈跟踪中寻找更多的东西吗?

我在其他线程上设置在主线程上获取的对象的属性是否有问题?即,objectA在 main 上获取,然后将其传递给另一个线程并执行类似的操作objectA.someNumber = [NSNumber numberWithInt:2]

4

2 回答 2

0

正是因为您的获取请求正在您的应用程序阻塞的主线程上运行。请记住,主线程是一个串行队列,并且在您的获取请求完成之前不会运行其他块(或事件)(即使理论上它可以,因为您的块处于等待状态)。这就解释了为什么当你中断时你总是会遇到 _psanch_mutexwait。

您应该在另一个队列上运行您的获取请求,并在必要时使用主队列上的结果。实现此目的的一种方法是使用以下模式:

- (void) fetchRequest1
{
     dispatch_async(not_the_main_queue, ^(void) {

         // Code the request here.

         // Then use the result on the main if necessary.
         dispatch_async(dispatch_get_main_queue(), ^(void) {
             // Use the result on the main queue.
         });
     });
}

另请注意,通常不需要在主队列上运行任何内容。事实上,如果您在该线程上运行得越少,您的应用程序通常会运行得更顺畅。当然,有些事情必须在那里完成,在这种情况下,您可以使用以下模式来确保它是:

- (void) runBlockOnMainThread:(void(^)(void))block
{
    dispatch_queue_t thisQ = dispatch_get_current_queue();
    dispatch_queue_t mainQ = dispatch_get_main_queue();

    if (thisQ != mainQ)
        dispatch_sync(mainQ, block);
    else
        block();
}
于 2013-04-21T14:47:25.960 回答
0

我在其他线程上设置在主线程上获取的对象的属性是否有问题?即,在 main 上获取 objectA,然后将其传递给另一个线程并执行类似 objectA.someNumber = [NSNumber numberWithInt:2] 的操作?

是的!我试过这个。

当你在 ThreadA 中获取 ObjA,然后将它传递给 ThreadB 进行一些操作时,它就会陷入死锁。

于 2013-06-24T09:28:58.110 回答