2017-01-15 50 views
0

我正在使用GPUImage框架,我注意到編譯器會自動跳過setColorAverageProcessingFinishedBlock的括號內的所有內容。它完全跳過這些內容並繼續執行代碼中的其他所有內容。一旦執行了其他所有內容,它就會回到括號內的內容。顯然,這具有意想不到的副作用。Objective-C塊不跳過代碼,然後執行它

NSMutableArray *redValues = [NSMutableArray array]; 
NSMutableArray *arrayOne = [NSMutableArray array]; 
NSUInteger arrayOneLength = [arrayOne count]; 

__block int counter = 0; 
int amount = 1; 
float totalOne, diffForAverage; 
NSInteger j; 

GPUImageVideoCamera *videoCamera = [[GPUImageVideoCamera alloc] initWithSessionPreset:AVCaptureSessionPreset640x480 cameraPosition:AVCaptureDevicePositionBack]; 
videoCamera.outputImageOrientation = UIInterfaceOrientationPortrait; 

GPUImageAverageColor *averageColor = [[GPUImageAverageColor alloc] init]; 
[averageColor setColorAverageProcessingFinishedBlock:^(CGFloat redComponent, CGFloat greenComponent, CGFloat blueComponent, CGFloat alphaComponent, CMTime frameTime) 
{ // the compiler runs until here, then skips everything within these brackets 
    NSLog(@"%f", redComponent); 
    [redValues addObject:@(redComponent * 255)]; 
}]; // after the brackets close, it executes everything that is below this 
// once everything below this has been executed, it goes back to the brackets and executes 
// everything between them 

[videoCamera addTarget:averageColor]; 
[videoCamera startCameraCapture]; 

dispatch_after(dispatch_time(DISPATCH_TIME_NOW, 27 * NSEC_PER_SEC), dispatch_get_main_queue(), ^{ 
    [videoCamera stopCameraCapture]; 
}); 

totalOne = [redValues[24] floatValue]; 
float average = totalOne/amount; 
NSUInteger redValuesLength = [redValues count]; 

for (j = (counter + 24); j < (redValuesLength - 24); j++) 
{ 
    diffForAverage = average - [redValues[j + 1] floatValue]; 

    if (diffForAverage > -1 && diffForAverage < 1) 
    { 
     totalOne += [redValues[j + 1] floatValue]; 
     amount++; 
     [arrayOne addObject:[NSNumber numberWithInt:(j - 24)]]; 
     counter++; 
    } 
} 

我該如何解決這個問題?

+0

您是否閱讀過'setColorAverageProcessingFinishedBlock'的文檔來理解它應該做什麼? – jtbandes

+0

@jtbandes是的,我已經看到它在使用的例子。沒有像我遇到的事情被列出。 – fi12

+0

對我來說'FinishedBlock'這個詞表明這正是它應該做的。該塊將在「色彩平均處理完成」時執行。 – jtbandes

回答

2

您發佈的代碼與其應該工作的完全相同。顏色平均處理需要一段時間,因此它在後臺線程上完成,因此主線程不會停止。處理完成後,然後該塊被調用。

在處理完成之前不應執行的任何代碼需要在內部執行該塊。

+0

此答案的問題是隻記錄一個值。我需要從攝像機輸入錄製數百個。 – fi12

+0

你有什麼建議嗎? – fi12

3

上述代碼有兩個問題:一個是內存管理問題,另一個是對塊的工作原理的誤解。

首先,您要在方法中創建GPUImageVideoCamera實例,但不會將其保留爲實例變量。我將假設這是使用自動引用計數的代碼,如果這是真的,則在您的方法完成後,此相機實例將被釋放。最好的情況是,在解除分配之前,您可能會從相機捕獲一幀。在最壞的情況下,隨着攝像機和附在其上的整個濾波器鏈在操作中解除分配,這將會崩潰。

在您的包含類上創建一個實例變量,並將GPUImageVideoCamera實例賦值給它,以使其持續足夠長時間以便有用。

上述第二個問題是關於塊如何以及何時執行的誤解。塊只是您可以傳遞的代碼的一部分,並且它們不一定與周圍的其他代碼串行執行。

在這種情況下,您提供的塊是一個回調,在通過平均顏色操作處理每幀視頻後將觸發回調。這個處理是在一個背景隊列上異步發生的,你必須設計你的代碼來確認這一點。

如果您想要構建X值,請將每個度量值添加到該塊內的數組中,然後在該塊內檢查是否要達到X值。在那個時候,平均和他們做任何事情。基本上,在塊中添加一個檢查,並將它後面的代碼移動到要運行的塊中,只要計數大於X.您可能希望在此時停止捕獲攝像頭,如果這是您所需要的。