2012-01-03 15 views
4

私はかなり遅い(100-200ms)drawRectメソッドを持っています。時間を節約するために、結果をキャッシュする必要があります。私はこのような実際のキャッシングを行っています:メインスレッドで優先度の低いタスクをスケジュールします

// some code to check if caching would be desirable goes here. If it is desirable, then 
UIGraphicsBeginImageContext(viewSize); 
CGContextRef c = UIGraphicsGetCurrentContext(); 
[view.layer renderInContext: c]; 
UIImage* image = UIGraphicsGetImageFromCurrentImageContext(); 
[self.cachedImageArray addObject:image]; 
UIGraphicsEndImageContext(); 

キャッシング自体には最大40msかかることがあります。これはまだ簡単に値する。しかし、キャッシングはすべてがレンダリングされるまで待たなければなりません。そうしないと、キャッシュが間違ってしまうことになります。さらに、キャッシングは優先度の低いタスクです。すべてが表示されたら、他のことが起こっている可能性があります。そうであれば、キャッシュは待機することができます。しかし、UIKitを使用するので、それはメインスレッド上になければなりません。

何らかの遅延を入れているのではなく、このように待機する防弾方法はありますか?

+2

なぜキャッシュタスクはメインスレッド上になければならないのですか?結果をメインスレッド( 'performSelectorOnMainThread'またはGCDのmagic' dispatch_async(dispatch_get_main_queue()、^ {})経由で)に送信(または表示)できませんでしたか?あなたの 'drawRect'? –

+3

グラフィックスコンテキストへの描画は、iOS 4のようにスレッドセーフであり、メインスレッド上で実行する必要はありません。' dispatch_async() 'を使ってバックグラウンドスレッドにこの全部をキックすることができます。 –

答えて

1

キャッシュ自体をメインスレッドで実行する必要はありません。画像コンテキストまたはビットマップデータのコピー/参照を取得し、レンダリングが完了したときにのみNSThreadを使用して起動することができます。例:

- (void) drawRect:(CGRect)rect { 
    do_rendering_here(); 
    // when rendering completed: 
    NSThread *t = [[NSThread alloc] initWithTarget:self selector:@selector(doCaching:) object:c]; 
    [t start]; 
    [t release]; 
} 

- (void) doCaching:(CGContextRef)ctx { 
    // do whatever kind of caching is needed 
} 
+0

USing 「NSThreadはまだ許可されていますが、Appleはほとんどのタスクでこれを推奨していますが、Grand Central Dispatchを使用して、@ MichaelDautermannの解決策を使用することをお勧めします。 –

+0

申し訳ありませんが、iOS5対応デバイスを所有していないため、これらの新しいAPIは使用できません。 3.1.3ヘッダーから構築された古いツールチェーン。 –

+1

@ H2CO3 - GCDはiOS 4.0に付属していますので、しばらくサポートされています。また、バックグラウンドスレッドで何かを実行するために、NSThreadインスタンスの複雑な割り当てを行う必要はありません。単にNSObjectの '-performSelectorInBackground:withObject:'を使うだけです。 –

関連する問題