应用程序因并发访问变量而崩溃

时间:2014-09-23 21:57:21

标签: ios

我一直试图调试这个问题一段时间,我不知道我能做些什么。我不是很擅长我正在做的事情,所以请以任何合乎逻辑的谬误来阻止我。

我收到EXC_BAD_ACCESS代码= 1错误。它偶尔会发生。每当它崩溃时,符号窗口显示所访问的所有内容都不是nil,所以我假设这意味着当线程进入汇编时,数据被另一个线程修改并导致崩溃。

我为我的视频输出启动了一个串行调度队列,这样界面运行得更顺畅(否则,我的游戏不稳定)

- (void) addVideoDataOutput {
    // (1) Instantiate a new video data output object
    AVCaptureVideoDataOutput * captureOutput = [[AVCaptureVideoDataOutput alloc] init];
    captureOutput.alwaysDiscardsLateVideoFrames = YES;

    // (2) The sample buffer delegate requires a serial dispatch queue
    dispatch_queue_t queue;
    queue = dispatch_queue_create("com.example.tangible.videooutput", DISPATCH_QUEUE_SERIAL);
    [captureOutput setSampleBufferDelegate:self queue:queue];

    // (3) Define the pixel format for the video data output
    NSString * key = (NSString*)kCVPixelBufferPixelFormatTypeKey;
    NSNumber * value = [NSNumber numberWithUnsignedInt:kCVPixelFormatType_32BGRA];
    NSDictionary * settings = @{key:value};
    [captureOutput setVideoSettings:settings];

    // (4) Configure the output port on the captureSession property
    [self.captureSession addOutput:captureOutput];
}

每次来自摄像机的数据准备就绪时,该线程就会启动并运行。这会导致对" com.example.tangible.videooutput"中访问的变量进行可能的并发读写操作。我正在使用DISPATCH_QUEUE_SERIAL,这意味着一切都在队列中一次运行一个。这是否意味着队列外的不同线程正在编辑这些变量? (我不认为这发生在我的代码中)

基于我的假设,多个线程同时访问某些变量(由于我使用的是串行调度队列,因此不应该发生这种情况),我已将线程访问的变量更改为原子并复制。这并没有阻止崩溃。

在我调用任何操作之前,我觉得我需要在每个列表中进行深层复制(这些是同时访问的链接列表)的阶段,我觉得这样做是浪费和不必要的

我不明白为什么要同时访问这些变量,因为我使用的是串行调度队列,而且我不相信该队列中线程之外的任何内容都会访问这些链接列表。

这是崩溃(有时)和变量的图片。 enter image description here

这是一个回溯:

* thread #6: tid = 0x8ed94, 0x0000000191b641dc libobjc.A.dylib`objc_msgSend + 28, queue = 'com.example.tangible.videooutput'
    frame #0: 0x0000000191b641dc libobjc.A.dylib`objc_msgSend + 28
  * frame #1: 0x00000001000f5508 Tangible`-[ControlScene removeBlocks](self=0x000000015450cc60, _cmd=0x0000000100556388) + 2096 at ControlScene.mm:342
    frame #2: 0x00000001000f5764 Tangible`-[ControlScene updateBlocks:](self=0x000000015450cc60, _cmd=0x00000001005559fe, b=0x000000017045a580) + 276 at ControlScene.mm:362
    frame #3: 0x00000001000e7e08 Tangible`-[StageViewController frameReady:](self=0x0000000154612f70, _cmd=0x0000000100555a0c, frame=<unavailable>) + 640 at StageViewController.mm:94
    frame #4: 0x00000001000ebbb0 Tangible`-[VideoSource captureOutput:didOutputSampleBuffer:fromConnection:](self=0x0000000170261e80, _cmd=0x0000000183fe21c9, captureOutput=0x0000000170223840, sampleBuffer=0x00000001586091e0, connection=0x0000000170610080) + 340 at VideoSource.mm:131
    frame #5: 0x0000000183f683c4 AVFoundation`__74-[AVCaptureVideoDataOutput _AVCaptureVideoDataOutput_VideoDataBecameReady]_block_invoke + 412
    frame #6: 0x000000019212c014 libdispatch.dylib`_dispatch_call_block_and_release + 24
    frame #7: 0x000000019212bfd4 libdispatch.dylib`_dispatch_client_callout + 16
    frame #8: 0x00000001921324a8 libdispatch.dylib`_dispatch_queue_drain + 640
    frame #9: 0x000000019212e4c0 libdispatch.dylib`_dispatch_queue_invoke + 68
    frame #10: 0x00000001921330f4 libdispatch.dylib`_dispatch_root_queue_drain + 104
    frame #11: 0x00000001921334fc libdispatch.dylib`_dispatch_worker_thread2 + 76
    frame #12: 0x00000001922c16bc libsystem_pthread.dylib`_pthread_wqthread + 356

请指教。我不明白发生了什么,我已经有这个错误了很长一段时间。我很乐意根据要求提供任何其他代码片段。

2 个答案:

答案 0 :(得分:0)

每次调用函数时,您似乎都创建了一个新的调度队列: queue = dispatch_queue_create(“com.example.tangible.videooutput”,DISPATCH_QUEUE_SERIAL);

所以他们可能无法同步。您是否尝试过仅创建一次队列?

答案 1 :(得分:0)

问题不在于并发访问,因此将变量设为原子或对其进行锁定并没有帮助这种情况。

我在可变数组中有链表,但是这些可变数组并没有被声明为强。每个链接列表节点都指向的对象也不是。因此,通过将这些属性更改为strong,所有崩溃都会消失=)