2014-09-23 63 views
0

我一直在試圖調試這個問題一段時間,我不知道我能做些什麼。我不擅長我在做什麼,所以請阻止我做任何邏輯上的謬誤。應用程序正在從併發訪問變量崩潰

我得到一個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,這意味着所有內容在隊列中一次只運行一個。這是否意味着隊列外的另一個線程正在編輯這些變量? (我不認爲這發生在我的代碼中)

基於我的假設,多個線程同時訪問一些變量(這不應該發生,因爲我正在使用串行調度隊列),我有將線程訪問的變量更改爲原子和複製。這並沒有阻止事故的發生。

我在一個階段,我覺得我需要做一個深度複製(這些是同時訪問的鏈接列表)每個列表之前,我打電話給他們的任何操作,我覺得這是浪費和不必要。

我不明白爲什麼這些變量被同時訪問,因爲我使用的是串行調度隊列,我不相信該隊列中的線程之外的任何東西都訪問這些鏈接列表。

這裏是它崩潰(有時)和變量的圖片。 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 

請指點。我不明白髮生了什麼,並且我已經有了這個錯誤很長一段時間了。我會很樂意根據要求提供任何其他代碼片段。

+0

您能分享更多信息嗎? (哪個線程?總是相同的地方?請分享完整的堆棧跟蹤。)您可以共享更多信息:視頻處理線程正在做什麼以及主線程(或任何其他線程)在同一模型中執行什麼操作?使用'atomic'和'copy'來實現線程安全性的建議有點令人擔憂(通常你會使用某種形式的鎖定或同步隊列來進行變異結構),但是我毫不猶豫地跳過這個結論而沒有更多的信息。 – Rob 2014-09-24 01:43:38

+0

我不太確定你的意思是完整的堆棧跟蹤。這足夠嗎? http://i.imgur.com/6SLtBVw.png – joegreen0628 2014-09-24 02:14:51

+0

我不認爲視頻處理線程以外的任何線程都在爲同一模型做任何事情。正如您在堆棧追蹤中看到的,線程3是唯一包含我寫的代碼的東西。或者我不正確地讀取堆棧跟蹤? – joegreen0628 2014-09-24 02:17:39

回答

0

看起來您每次調用該函數時都會創建一個新的調度隊列: queue = dispatch_queue_create(「com.example.tangible.videooutput」,DISPATCH_QUEUE_SERIAL);

所以他們可能無法同步。你有沒有試過只創建一次隊列?

+1

歡迎來到SO。請求澄清和更多信息請使用註釋 – 2014-09-23 23:20:53

+0

我剛剛嘗試讓隊列變成一個實例變量然後運行它 - 相同事情發生了,指針訪問不好。 – joegreen0628 2014-09-23 23:28:03

0

這個問題不是併發訪問,所以使變量原子化或對其進行鎖定並沒有幫助。

我已經鏈接了可變數組內的列表,但這些可變數組沒有被聲明爲強。每個鏈接列表節點都沒有指向的對象。因此,通過將這些屬性更改爲強大,所有崩潰消失=)

相關問題