2011-11-07 61 views
2

我正在爲iPad構建一個多線程應用程序。我有這個類從影片剪輯中提取幀,我有一個UIScrollView來顯示我提取的東西。框架提取器運行在不同的線程中,我只想在提取一定數量的框架後纔開始構建滾動視圖。因此,我創建了這個名爲buffering的BOOL屬性,它通過線程進行更新。我的視圖控制器觀察這個屬性,並且只有在這個屬性等於NO NO開始構建ScrollView之後。iPad GUI僅在觸摸後更新

問題是,在構建方法被調用後,我沒有看到GUI中的任何更改。我只能看到滾動視圖後,我觸摸屏幕

下面有什麼即時通訊做:

要創建線程:

[NSThread detachNewThreadSelector:@selector(startReading) toTarget:self withObject:nil];

在線程中運行的代碼:

-(void) startReadingWithTimeRange:(STimeRange *) timeRange; 
{ 
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init]; // Top-level pool 
    //setting the time range for reading the file 
    [assetReader setTimeRange:timeRange.timeRange]; 

    //start reading 
    [assetReader startReading]; 

    //declearing about the buffer 
    CMSampleBufferRef buffer; 
    int z = 0; 
    while ([assetReader status]==AVAssetReaderStatusReading) 
    { 
     z++; 
     //reading buffer 
     buffer = [assetReaderTrackOutput copyNextSampleBuffer]; 

     if (buffer == NULL) break; 
     //converting the buffer to UIImage 
     UIImage *frameImage = imageFromSampleBuffer(buffer); 
     CMTime time = CMSampleBufferGetOutputPresentationTimeStamp(buffer); 
     NSLog(@"###duration %lld",time.value/time.timescale); 


     SFrame *frame = [[SFrame alloc] initWithImage:frameImage andTime:time]; 
     //add it to the frame array 
     [framesArray addObject:frame]; 

     [frame release]; 
     //check if buffer is not null and needed release 


     //release the buffer 
     CFRelease(buffer); 


     if ([framesArray count] > 100 && self.buffering) { 
      [self willChangeValueForKey:@"buffering"]; 
      self.buffering = NO; 
      [self didChangeValueForKey:@"buffering"]; 

     } 


    } 
    [pool release]; 

} 

我真的很無知我真的很感謝任何幫助

+0

您的選擇器與方法名稱不匹配... – jakev

+0

'startReading'只能調用'startReadingWithTimeRange:'正確範圍 –

+0

有趣的部分可能是您實際「構建滾動視圖」的代碼。我的猜測是你需要一個'setNeedsDisplay'調用。 – mrueg

回答

1

首先不要調用willChangeValueForKey和didChangeValueForKey,因爲您只會使KVO通知觸發兩次,它已經由self.buffering = NO觸發;

@synchronized (self) { 
    self.buffering = NO; 
} 

你可以交替使用performSelectorOnMainThread來調用一個緩衝方法如:

[self performSelectorOnMainThread:@selector(buffering:) withObject:[NSNumber numberWithBool:YES] waitUntilDone:NO]; 

如果

其次,主線程之外財產/伊娃的變化應該在@synchronized塊如內部完成這樣做並不能解決你的問題,那麼你的代碼中可能會遇到另一個問題需要在某些視圖或種類上調用setNeedsDisplay。

你沒有說KVO通知會發生什麼,你不明白爲什麼你明確地試圖發送它嗎?

+1

他應該使用'performSelectorOnMainThread:...'。我會下注,他不會跳到他的KVO通知的主線程中,因此最終(非法)在後臺線程上執行UIKit任務。 – Tommy

+0

只是爲了記錄它很容易檢查你的踩[NSThread isMainThread]並看看 – valexa