Ios GLKTextureLoader-textureWithCGImage:选项:队列:completionHandler:malloc错误

Ios GLKTextureLoader-textureWithCGImage:选项:队列:completionHandler:malloc错误,ios,memory-management,opengl-es,glkit,glktextureloader,Ios,Memory Management,Opengl Es,Glkit,Glktextureloader,我正在使用GLKTextureLoader实例异步加载纹理: NSDictionary *options = [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:GLKTextureLoaderOriginBottomLeft]; GLKTextureLoader *asyncLoader = [[G

我正在使用
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:**对象0xa0cb3c0的错误:未在控制台中分配要释放的指针
警告。回溯显示错误发生在
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 imageName:imageName]
在工作。知道为什么吗?

您正在使用异步方法处理此项。执行发布的可能不是asyncLoader,而是其他东西

如果您在本地将映像声明为UIImage,调用此asyncLoader以运行,然后立即退出当前stackFrame(即调用此调用的当前方法),则传递的UIImage可能在您在asyncLoader中使用它之前已被释放。(如果UIImage被传入,但在调用堆栈帧中被释放,或者如果它很弱,并且持有对它的引用的东西在asyncLoader运行之前将其删除,也会发生同样的情况)


我建议对图像设置一个强@property(并在viewController的viewDidUnload中将其设置为nil),然后这个问题应该会消失。

图像从哪里来?@borrden我已经用一些细节更新了这个问题。很抱歉回复太晚。在完成块中,您有以下代码
if(completionHandler)completionHandler(textureName)
可能会发布此处调用的
completionHandler()
函数的源代码。纹理加载程序在崩溃发生之前没有到达自己的
completionHandler
块(即,
if(outError)…
行中的任何代码都没有运行),因此我认为它与此无关。我的
completionHandler
块中的代码因情况而异,但主要涉及将纹理绑定和绘制到FBO(但正如我所说,它从未运行)。如果
GLKTextureLoader
实例没有强烈捕获对传入图像的引用,我会感到惊讶。可能需要注意的是,您没有将
UIImage
传递到方法中,而是将
CGImageRef
传递到方法中。。。对此的引用是否仍然依赖于挂起的
UIImage
?我将更新我的问题,更详细地介绍一下图像的来源,但在这里我只想说,我认为您关于图像引用所有权的错误是正确的。