私はバックグラウンドスレッドでUIImagesを読み込み、iPadに表示しようとしています。しかし、画像にimageViewsのビュープロパティを設定すると、スタッターがあります。 私はすぐにその画像の読み込みがiOSの上で怠惰で考え出し、この問題の部分的な解決策を見つけた:iOSでの非レイジー画像の読み込み
CGImage/UIImage lazily loading on UI thread causes stutter
これは実際のスレッドでロードする画像を強制的に、しかし表示する際にスタッターがまだあります画像。
ここで私のサンプルプロジェクトを見つけることができます:http://www.jasamer.com/files/SwapTest.zip(編集:fixed version)、SwapTestViewControllerをチェックしてください。画像をドラッグしてスタッターを見てみてください。
私は吃音は、この(のforceload方法は、私は上記の投稿スタックオーバーフローの質問から取られたもの)であることを作成したテストコード:私は吃音ができる知っている理由は2つあります
NSArray* imagePaths = [NSArray arrayWithObjects:
[[NSBundle mainBundle] pathForResource: @"a.png" ofType: nil],
[[NSBundle mainBundle] pathForResource: @"b.png" ofType: nil], nil];
NSOperationQueue* queue = [[NSOperationQueue alloc] init];
[queue addOperationWithBlock: ^(void) {
int imageIndex = 0;
while (true) {
UIImage* image = [[UIImage alloc] initWithContentsOfFile: [imagePaths objectAtIndex: imageIndex]];
imageIndex = (imageIndex+1)%2;
[image forceLoad];
//What's missing here?
[self performSelectorOnMainThread: @selector(setImage:) withObject: image waitUntilDone: YES];
[image release];
}
}];
回避:
(1)Appleは写真アプリに吃音せずに画像をロードすることができます
(2)PLACEHOLDER1とPLACEHOLDER2後に吃音が発生することはありません。このコードは、上記のコードのこの修正版では一度表示されています:
ただし、すべての画像をメモリに保存できません。
これは、forceLoadが完全なジョブを実行しないことを意味します。イメージが実際に表示される前に何か他のことが起こっています。 それは誰が知っていますか、どのようにバックグラウンドスレッドに入れることができますか? Tommysのヒントのいくつかを使用し
おかげで、ジュリアン
更新
。 CGSConvertBGRA8888toRGBA8888は非常に時間がかかるので、遅れの原因となっている色変換のようです。 そのメソッドの(反転した)呼び出しスタックを次に示します。
Running Symbol Name
6609.0ms CGSConvertBGRA8888toRGBA8888
6609.0ms ripl_Mark
6609.0ms ripl_BltImage
6609.0ms RIPLayerBltImage
6609.0ms ripc_RenderImage
6609.0ms ripc_DrawImage
6609.0ms CGContextDelegateDrawImage
6609.0ms CGContextDrawImage
6609.0ms CA::Render::create_image_by_rendering(CGImage*, CGColorSpace*, bool)
6609.0ms CA::Render::create_image(CGImage*, CGColorSpace*, bool)
6609.0ms CA::Render::copy_image(CGImage*, CGColorSpace*, bool)
6609.0ms CA::Render::prepare_image(CGImage*, CGColorSpace*, bool)
6609.0ms CALayerPrepareCommit_(CALayer*, CA::Transaction*)
6609.0ms CALayerPrepareCommit_(CALayer*, CA::Transaction*)
6609.0ms CALayerPrepareCommit_(CALayer*, CA::Transaction*)
6609.0ms CALayerPrepareCommit_(CALayer*, CA::Transaction*)
6609.0ms CALayerPrepareCommit
6609.0ms CA::Context::commit_transaction(CA::Transaction*)
6609.0ms CA::Transaction::commit()
6609.0ms CA::Transaction::observer_callback(__CFRunLoopObserver*, unsigned long, void*)
6609.0ms __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__
6609.0ms __CFRunLoopDoObservers
6609.0ms __CFRunLoopRun
6609.0ms CFRunLoopRunSpecific
6609.0ms CFRunLoopRunInMode
6609.0ms GSEventRunModal
6609.0ms GSEventRun
6609.0ms -[UIApplication _run]
6609.0ms UIApplicationMain
6609.0ms main
彼が提案した最後のビットマスクの変更は、悲しいことに何も変わっていません。
ありがとうございます。この問題を解決しようとしている約1000個のクロムウィンドウを開きましたが、誰も何の考えもしていませんでした。 – Sheepdogsheep
さらに、 'NSBundle'はスレッドセーフではありません。 – SK9