我使用GCD时为什么会出现错误EXC_BAD_INSTRUCTION(code = EXC_I386_INVOP,subcode = 0x0)

时间:2013-08-01 13:44:32

标签: ios objective-c grand-central-dispatch

有人可以解释一下为什么我在dispatch_semaphore_wait中出现错误EXC_BAD_INSTRUCTION(code = EXC_I386_INVOP,subcode = 0x0),代码如下:

-(void) initialize {
  dispatch_queue_t queue = dispatch_queue_create("My queue", NULL);
  dispatch_semaphore_t sem = dispatch_semaphore_create(1);
  self.queue = queue;
  self.sem = sem;
  self.myarray = [[NSMutableArray alloc]init];
  [self.myarray addObject: [[MyObject alloc] init]];
}
-(MyObject *) method1 {
  //do something
  dispatch_semaphore_wait(self.sem, DISPATCH_TIME_FOREVER);
  MyObject *obj = [self.myarray objectAtIndex:0];
  dispatch_barrier_sync(self.queue, ^{
    [self.myarray removeObjectAtIndex:0];
  });
  return obj;
}

-(void) method2:(MyObject *)object {
  //do something
  dispatch_barrier_async(self.queue, ^{
    [self.myarray addObject:object];
    dispatch_semaphore_signal(self.sem);
  });
}

我发现了类似的问题Why does this code cause "EXC_BAD_INSTRUCTION"?,但在我的情况下,我使用的是ARC而且我没有明确写出dispatch_release(sem);

3 个答案:

答案 0 :(得分:2)

您在sem方法中创建的initialize是本地作用于该方法的。它需要其他方法可访问。如果您有一个名为sem的iVar正在尝试分配,则通过在initialize中声明一个局部变量来隐藏它。 (顺便说一句,与queue相同。)

此外,您似乎在这里打字错误,因为您拨打dispatch_semaphore_wait(sen, DISPATCH_TIME_FOREVER);(即se n vs se m

答案 1 :(得分:1)

您无法在没有足够保护的情况下同时访问阵列self.myarray。您可以在串行队列-addObject:上使用-removeObjectAtIndex:self.queue修改数组,但是使用-objectAtIndex:进行读取时没有任何保护。这意味着你可能在写信的同时阅读它,这是不安全的。您还需要将-objectAtIndex:调用放在串行队列中。

此外,您正在使用具有串行队列的屏障功能,这没有任何意义。

-(MyObject *) method1 {
  //do something
  dispatch_semaphore_wait(self.sem, DISPATCH_TIME_FOREVER);
  __block MyObject *obj;
  dispatch_sync(self.queue, ^{
    obj = [self.myarray objectAtIndex:0];
    [self.myarray removeObjectAtIndex:0];
  });
  return obj;
}

-(void) method2:(MyObject *)object {
  //do something
  dispatch_async(self.queue, ^{
    [self.myarray addObject:object];
    dispatch_semaphore_signal(self.sem);
  });
}

答案 2 :(得分:0)

当您运行CPU不支持的(向量)扩展时,会发生这种崩溃。

例如,在“project-settings / build-settings / Code Generation”下的xcode 5中,设置 “启用其他矢量扩展”到“AVX2”。构建可执行文件。

现在在:

上运行它
  • Intel Core i5:它会在'exc_i386_invop subcode = 0x0'时崩溃(编译器决定使用avx2的地方)。
  • 英特尔酷睿i7:它会起作用。