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

Ios 应用程序因并发访问变量而崩溃,ios,Ios,我已经试着调试这个问题一段时间了,我不知道我能做什么。我不太擅长我正在做的事情,所以请阻止我的任何逻辑谬论 我得到一个EXC\u BAD\u访问代码=1错误。它偶尔发生。每当它崩溃时,符号窗口显示被访问的所有内容都不是nil,因此我假设这意味着当线程进入汇编时,数据被另一个线程修改并导致崩溃 我为我的视频输出启动了一个串行调度队列,这样界面就会运行得更顺畅。否则,我的游戏会很混乱 - (void) addVideoDataOutput { // (1) Instantiate a new

我已经试着调试这个问题一段时间了,我不知道我能做什么。我不太擅长我正在做的事情,所以请阻止我的任何逻辑谬论

我得到一个EXC\u BAD\u访问代码=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.contractible.videooutput中访问的变量进行并发读写。我使用的是DISPATCH\u QUEUE\u SERIAL,因此这意味着队列中的所有内容一次运行一个。这是否意味着队列外的另一个线程正在编辑这些变量?我认为在我的代码中不会发生这种情况

基于我的假设,即多个线程同时访问某些变量,这是不应该发生的,因为我使用的是串行调度队列,因此我将线程访问的变量更改为原子变量和副本变量。这并没有阻止撞车

我正处于这样一个阶段,我觉得我需要做一个深度复制,这些是链接列表,在我调用任何操作之前,每个列表都会同时被访问,我觉得这是浪费和不必要的

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

下面是它有时崩溃的地方的图片,以及变量。

以下是回溯:

* 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

请给我一些建议。我不明白发生了什么,我已经有一段时间的错误。我很乐意根据请求提供任何其他代码片段。

每次调用函数时,您似乎都创建了一个新的调度队列: queue=dispatch\u queue\u createcom.example.有形.videooutput,dispatch\u queue\u SERIAL


因此,它们可能无法同步。您是否只尝试创建一次队列?

问题不是并发访问,因此将变量设置为原子变量或对其加锁无助于解决问题


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

欢迎使用So。为了请求澄清和更多信息,请使用注释。我只是尝试将队列设置为实例变量,然后运行它,同样的事情发生了。指针访问错误。你能分享更多关于崩溃的信息吗?哪根线?总是在同一个地方?请共享完整堆栈跟踪。你能分享更多关于视频处理线程在做什么以及主线程或其他线程在同一型号上做什么的信息吗?使用atomic和copy来实现线程安全的建议有点令人担忧,通常情况下,您会使用某种形式的锁或同步队列来实现变异结构,但如果没有更多信息,我会犹豫是否要得出这个结论。我不太确定您所说的完整堆栈跟踪是什么意思。这够了吗?我认为除了视频处理线程之外,没有其他线程对同一个模型做过任何事情。正如您在堆栈跟踪中看到的,线程3是唯一包含我编写的代码的东西。或者我读取堆栈跟踪不正确?视频处理线程还更新了两个场景。我应该把它放回主线程吗?是的,我会尝试将SKScene更新发送回主线程。从您关于与atomic/copy同步的另一次对话中,我假设主线程正在尝试访问该视频处理线程正在更新的模型。我想情况并非如此。