我一直在試圖調試這個問題一段時間,我不知道我能做些什麼。我不擅長我在做什麼,所以請阻止我做任何邏輯上的謬誤。應用程序正在從併發訪問變量崩潰
我得到一個EXC_BAD_ACCESS代碼= 1錯誤。偶爾發生。每當它崩潰時,符號窗口顯示所有被訪問的內容都不是零,所以我假設這意味着當線程進入彙編時,數據被另一個線程修改並導致崩潰。
我開始一個串行調度隊列爲我的視頻輸出,使接口運行更流暢(否則,我的比賽是波濤洶涌)
- (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,這意味着所有內容在隊列中一次只運行一個。這是否意味着隊列外的另一個線程正在編輯這些變量? (我不認爲這發生在我的代碼中)
基於我的假設,多個線程同時訪問一些變量(這不應該發生,因爲我正在使用串行調度隊列),我有將線程訪問的變量更改爲原子和複製。這並沒有阻止事故的發生。
我在一個階段,我覺得我需要做一個深度複製(這些是同時訪問的鏈接列表)每個列表之前,我打電話給他們的任何操作,我覺得這是浪費和不必要。
我不明白爲什麼這些變量被同時訪問,因爲我使用的是串行調度隊列,我不相信該隊列中的線程之外的任何東西都訪問這些鏈接列表。
這裏是它崩潰(有時)和變量的圖片。
這裏是一個回溯:
* 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
請指點。我不明白髮生了什麼,並且我已經有了這個錯誤很長一段時間了。我會很樂意根據要求提供任何其他代碼片段。
您能分享更多信息嗎? (哪個線程?總是相同的地方?請分享完整的堆棧跟蹤。)您可以共享更多信息:視頻處理線程正在做什麼以及主線程(或任何其他線程)在同一模型中執行什麼操作?使用'atomic'和'copy'來實現線程安全性的建議有點令人擔憂(通常你會使用某種形式的鎖定或同步隊列來進行變異結構),但是我毫不猶豫地跳過這個結論而沒有更多的信息。 – Rob 2014-09-24 01:43:38
我不太確定你的意思是完整的堆棧跟蹤。這足夠嗎? http://i.imgur.com/6SLtBVw.png – joegreen0628 2014-09-24 02:14:51
我不認爲視頻處理線程以外的任何線程都在爲同一模型做任何事情。正如您在堆棧追蹤中看到的,線程3是唯一包含我寫的代碼的東西。或者我不正確地讀取堆棧跟蹤? – joegreen0628 2014-09-24 02:17:39