ビューを更新するバックグラウンドタスクがあります。そのタスクは、-setNeedsDisplayを呼び出してビューを描画します。問題を求めるバックグラウンドタスクから-setNeedsDisplayを呼び出していますか?
これは動作します:
- (void) drawChangesTask;
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
if (pixels) {
drawChanges((UInt32 *) origPixels, (UInt32 *) pixels, CGBitmapContextGetBytesPerRow(ctx)/4, CGBitmapContextGetHeight(ctx), count--);
if (count < 0) {
count = 150;
}
else
[self performSelectorInBackground:@selector(drawChangesTask) withObject:nil ];
[self performSelectorOnMainThread:@selector(setNeedsDisplay) withObject:nil waitUntilDone:NO ];
}
[pool release];
}
これは動作しません:
- (void) drawChangesTask;
{
NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
if (pixels) {
drawChanges((UInt32 *) origPixels, (UInt32 *) pixels, CGBitmapContextGetBytesPerRow(ctx)/4, CGBitmapContextGetHeight(ctx), count--);
if (count < 0) {
count = 150;
}
else
[self performSelectorInBackground:@selector(drawChangesTask) withObject:nil ];
[self setNeedsDisplay];
}
[pool release];
}
誰もがなぜ知っていますか?私はそれが動作しないと言うとき、私はそれが数十回実行することを意味する、時々私はイメージの一部が上下にシフトした、または完全に空白を参照してください、そしてdeuggerはCoreGraphicsのどこかに "EXC_BAD_ACCESS
"
また、自分で自動解放プールを処理しないと、エラーメッセージが漏れてしまいます。それがなぜか分からない。私のdrawChanges()は新しいオブジェクトを作成しません。ここでエラーです:
2009-08-17 11:41:42.358 BlurApp[23974:1b30f] *** _NSAutoreleaseNoPool(): Object 0xd78270 of class NSThread autoreleased with no pool in place - just leaking
はい、performSelectorInBackgroundを使わずに直接呼び出すと、runloopはdrawRectを実行して呼び出すことはできません。あなたが遅れて後でそれを呼び出すと言うことをすれば、それは奇妙なクラッシュなしで動作します。 – mahboudz
これはまた、[self performSelectorOnMainThread:@selector(setNeedsDisplay)withObject:nil waitUntilDone:NO]を使用したときに動作する理由についても説明しています。 setNeedsDisplayを呼び出すperformSelectorInBackgroundは、drawChangesTaskと同じ関数/メソッドを呼び出し、drawChanges()関数はUIKitを呼び出さないことに注意してください。したがって、スレッドに敏感であるように見える唯一のものはsetNeedsDisplayであり、それをメインスレッドで実行すると問題はありません。 – mahboudz
私は今、2つの解決策を持っています:performSelectorは0の遅延の後に、performSelectorInBackgroundはperformSelectorOnMainThreadによって呼び出されるsetNeedDisplayと共にです。 – mahboudz