dispatch_semaphore_dispose上的EXC_BAD_INSTRUCTION(代码= EXC_I386_INVOP,子代码= 0x0) [英] EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) on dispatch_semaphore_dispose

查看:473
本文介绍了dispatch_semaphore_dispose上的EXC_BAD_INSTRUCTION(代码= EXC_I386_INVOP,子代码= 0x0)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在dispatch_semaphore_dispose上获得EXC_BAD_INSTRUCTION(code = EXC_I386_INVOP,子代码= 0x0),但是并不知道如何追踪这个的根本原因。我的代码使用dispatch_async,dispatch_group_enter等。

I am getting EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) on dispatch_semaphore_dispose but don't really know how to track down the root cause of this. My code makes use of dispatch_async, dispatch_group_enter and so on.

更新:
崩溃的原因是由于webserviceCall(见下面的代码) )永远不会调用onCompletion,当代码再次运行时,我收到错误EXC_BAD_INSTRUCTION。我确认这是事实,但不知道为什么或如何防止这种情况。

UPDATE: The cause of the crash is due to the fact that the webserviceCall (see code below) never calls onCompletion and when the code is run again, I got the error EXC_BAD_INSTRUCTION. I verified this is indeed the case, but not sure why or how to prevent this.

代码:

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0);
dispatch_group_t group = dispatch_group_create();

     for (...) {
        if (...) {
            dispatch_group_enter(group);
            dispatch_async(queue, ^{

               [self webserviceCall:url onCompletion:^{
                     dispatch_group_leave(group);
               }];
            });
        }
    }

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
    dispatch_group_wait(group, dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)));
    dispatch_sync(queue, ^{
        // call completion handler passed in by caller
    });
});


推荐答案

从您的堆栈跟踪,发生EXC_BAD_INSTRUCTION(代码= EXC_I386_INVOP,子代码= 0x0),因为 dispatch_group_t 在它仍然锁定时发布(等待 dispatch_group_leave

From your stack trace, EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0) occurred because dispatch_group_t was released while it was still locking (waiting for dispatch_group_leave).

根据您发现的情况,发生这种情况:

According to what you found, this was what happened :


  • dispatch_group_t group 已创建。 的保留计数= 1。

  • - [self webservice: onCompletion:] 捕获 的保留计数= 2。

  • dispatch_async 。,^ {dispatch_group_wait(group,...)...}); 再次捕获 的保留计数= 3。

  • 退出当前范围。 已发布。 的保留计数= 2。

  • dispatch_group_leave 从未被调用。

  • dispatch_group_wait 已超时。 dispatch_async 块已完成。 已发布。 的保留计数= 1。

  • 您再次调用了此方法。当 - [self webservice:onCompletion:] 再次被调用时,旧的 onCompletion 块被替换为新的。所以,旧的被发布。 的保留计数= 0。 被取消分配。这导致 EXC_BAD_INSTRUCTION

  • dispatch_group_t group was created. group's retain count = 1.
  • -[self webservice:onCompletion:] captured the group. group's retain count = 2.
  • dispatch_async(...., ^{ dispatch_group_wait(group, ...) ... }); captured the group again. group's retain count = 3.
  • Exit the current scope. group was released. group's retain count = 2.
  • dispatch_group_leave was never called.
  • dispatch_group_wait was timeout. The dispatch_async block was completed. group was released. group's retain count = 1.
  • You called this method again. When -[self webservice:onCompletion:] was called again, the old onCompletion block was replaced with the new one. So, the old group was released. group's retain count = 0. group was deallocated. That resulted to EXC_BAD_INSTRUCTION.

为了解决这个问题,我建议你应该找出为什么 - [self webservice:onCompletion:] 没有调用$ code> onCompletion 块,并修复它。然后确保下一次调用该方法将在上一次调用完成后发生。

To fix this, I suggest you should find out why -[self webservice:onCompletion:] didn't call onCompletion block, and fix it. Then make sure the next call to the method will happen after the previous call did finish.

如果您允许多次调用该方法,无论以前的呼叫是否完成,您可能会发现有人为您持有

In case you allow the method to be called many times whether the previous calls did finish or not, you might find someone to hold group for you :


  • 您可以将超时从2秒更改为 DISPATCH_TIME_FOREVER 或合理的时间,所有 - [self webservice:onCompletion] 应该调用他们的 onCompletion 块。因此, dispatch_async(...)中的块将保留给您。

    OR

  • 您可以将 group 添加到集合中,例如 NSMutableArray

  • You can change the timeout from 2 seconds to DISPATCH_TIME_FOREVER or a reasonable amount of time that all -[self webservice:onCompletion] should call their onCompletion blocks by the time. So that the block in dispatch_async(...) will hold it for you.
    OR
  • You can add group into a collection, such as NSMutableArray.

我认为这是为这个动作创建一个专用类的最佳方法。当您想要调用 webservice 时,您将创建一个类的对象,调用其上的方法,并将传递给完成块的方法释放该对象。在课堂上,有一个ivar的 dispatch_group_t dispatch_semaphore_t

I think it is the best approach to create a dedicate class for this action. When you want to make calls to webservice, you then create an object of the class, call the method on it with the completion block passing to it that will release the object. In the class, there is an ivar of dispatch_group_t or dispatch_semaphore_t.

这篇关于dispatch_semaphore_dispose上的EXC_BAD_INSTRUCTION(代码= EXC_I386_INVOP,子代码= 0x0)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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