有人可以解释一下为什么我在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);
答案 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”。构建可执行文件。
现在在:
上运行它