2

インスタンスを使用しGLKTextureLoaderて非同期的にテクスチャをロードしています。

NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] 
                                                    forKey:GLKTextureLoaderOriginBottomLeft];
GLKTextureLoader *asyncLoader = [[GLKTextureLoader alloc] initWithSharegroup:sharegroup];
[asyncLoader textureWithCGImage:image
                        options:options
                          queue:NULL
              completionHandler:^(GLKTextureInfo *textureInfo, NSError *outError) {
                  if (outError) [ISDebugger logError:outError inMethod:_cmd];
                  GLuint textureName = [textureInfo name];
                  if (completionHandler) completionHandler(textureName);
              }];

このコードを初めて実行すると、正常に動作します。ただし、2 回目malloc: *** error for object 0xa0cb3c0: pointer being freed was not allocatedは、コンソールに警告が表示されます。GLKTextureLoaderバックトレースは、自身のワーカー スレッドでエラーが発生したことを示しているようです。

* thread #16: tid = 0x3003, 0x91a32c91 libsystem_c.dylib`malloc_error_break, stop reason = breakpoint 1.1
    frame #0: 0x91a32c91 libsystem_c.dylib`malloc_error_break
    frame #1: 0x91a32e07 libsystem_c.dylib`free + 358
    frame #2: 0x011f5003 CoreGraphics`image_provider_finalize + 29
    frame #3: 0x01b144b3 CoreFoundation`CFRelease + 291
    frame #4: 0x0118d96c CoreGraphics`CGImageBlockSetRelease + 76
    frame #5: 0x0154646c GLKit`-[GLKTexture dealloc] + 65
    frame #6: 0x02184e3d libobjc.A.dylib`_objc_rootRelease + 47
    frame #7: 0x01549da0 GLKit`+[GLKTextureLoader commonTextureWithCGImage:options:error:lock:eaglContext:] + 277
    frame #8: 0x0154b77e GLKit`__71-[GLKTextureLoader textureWithCGImage:options:queue:completionHandler:]_block_invoke_0 + 140
    frame #9: 0x0232b330 libdispatch.dylib`_dispatch_call_block_and_release + 15
    frame #10: 0x0232c439 libdispatch.dylib`_dispatch_worker_thread2 + 302
    frame #11: 0x919dfb24 libsystem_c.dylib`_pthread_wqthread + 346

明らかに、テクスチャ ローダーが何かを過剰にリリースしているようです。ここで何が間違っていますか?


アップデート:

メソッドに渡される画像は、次のように取得されます。

NSString *bundlePath = [[NSBundle mainBundle] bundlePath];
NSString *imagePath = [bundlePath stringByAppendingPathComponent:imageFilename];
UIImage *uiImage = [UIImage imageWithContentsOfFile:imagePath];
CGImageRef image = [uiImage CGImage];

画像生成をこれに変更すると、エラーが発生しなくなりました。

UIImage *uiImage = [UIImage imageNamed:imageFilename];
CGImageRef image = [uiImage CGImage];

だから今、私は質問がなぜだと思いますか?キャッシュ動作が含まれていることは理解してい+imageNamed:ますが、なぜこのコードに影響するのでしょうか?


更新 2:

を使用してイメージを作成した場合も同様です[UIImage imageWithData:imageData](クラッシュが発生します)。のみ[UIImage imageNamed:imageName]が機能しているようです。理由はありますか?

4

1 に答える 1

2

このアイテムを処理するために非同期メソッドを使用しています。リリースを実行しているのは asyncLoader ではなく、別のものである可能性があります。

イメージをローカルで UIImage として宣言し、この asyncLoader を呼び出して実行し、すぐに現在の stackFrame (つまり、この呼び出しを行う現在のメソッド) を終了した場合、渡した UIImage は、何かを実行する前に解放されている可能性があります。 asyncLoader。(UIImage が渡されたが、呼び出し元のスタック フレームで解放された場合、またはそれが弱く、参照を保持しているものが asyncLoader の実行前にそれを削除した場合、同じことが起こります)。

画像から強力な @property を作成する (そして、viewController の viewDidUnload で nil に設定する) ことをお勧めします。そうすれば、この問題は解決するはずです。

于 2012-07-16T21:59:09.117 に答える