2011-11-07 16 views
2

iPad用のマルチスレッドアプリをビルドしています。私はムービークリップからフレームを抽出するこのクラスを持っており、私は抽出したものを表示するためにUIScrollViewを持っています。フレーム抽出プログラムは別のスレッドで実行されており、一定量のフレームを抽出した後にのみスクロールビューの作成を開始します。したがって、スレッドを更新するバッファリングと呼ばれるこのBOOLプロパティを作成しました。私のビューコントローラはこのプロパティを観察し、このプロパティが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]; 

} 
私は画面をタッチした後、私は何イムやっ

HERESにスクロールビューを見ることができます

私は本当に助けに感謝します。

+0

セレクタがメソッド名と一致しません... – jakev

+0

'startReading'は正しい範囲で' startReadingWithTimeRange: 'のみを呼び出します –

+0

興味深い部分は実際には"スクロールビューを作成する "コードでしょう。私の推測では、あなたはどこかで 'setNeedsDisplay'呼び出しを必要とするでしょう。 – mrueg

答えて

1

最初にKVO通知を2回だけ発生させるので、willChangeValueForKeyとdidChangeValueForKeyを呼び出さないでください。これはすでにself.buffering = NOによって起動されています。

第二に、メインスレッド外のプロパティ/ IVARの変化が@Synchronizedブロックなどの内部で実行する必要があります:

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

あなたが交互にバッファリング方法の例を呼び出すためにperformSelectorOnMainThreadを使用することができます。

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

場合これを実行しても問題は解決しない場合は、コードに別の問題がある可能性があります。いくつかのビューまたは種類のsetNeedsDisplayを呼び出す必要があります。

あなたはKVO通知で何が起こったかは言いませんでしたが、明示的に送信しようとした理由はありませんか?

+1

彼は 'performSelectorOnMainThread:...'を使うべきでしょう。彼は彼のKVO通知のメインスレッドにホップしないので、バックグラウンドスレッドでUIKitタスクを(不法に)実行することになります。 – Tommy

+0

レコードのためには、[NSThread isMainThread]を使ってトレッドを確認するのは簡単です – valexa

関連する問題