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
?我将更新我的问题,更详细地介绍一下图像的来源,但在这里我只想说,我认为您关于图像引用所有权的错误是正确的。