Я использую экземпляр 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);
}];
При первом запуске этот код работает нормально. Однако во второй раз я получаю предупреждение 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]
. Есть идеи, почему?
image
? - person borrrden   schedule 13.07.2012if (completionHandler) completionHandler(textureName);
, возможно, опубликуйте исходный код для функцииcompletionHandler()
, вызываемой здесь. - person idz   schedule 17.07.2012completionHandler
до того, как произойдет сбой (т. е. ни один код из строкиif (outError) ...
никогда не запускается), поэтому я не думаю, что это может быть связано. Код в блоке mycompletionHandler
варьируется от случая к случаю, но в основном включает привязку и отрисовку текстуры к FBO (но, как я уже сказал, он никогда не запускается). - person Stuart   schedule 17.07.2012