2012-07-08 3 views
2
내가 비동기 적 텍스처를로드 할 GLKTextureLoader 인스턴스를 사용하고

:GLKTextureLoader -textureWithCGImage : 옵션 : 큐 : completionHandler : malloc에 ​​오류

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 경고가 표시됩니다. 뭔가를 해제 이상 - 텍스처 로더는 것 같다,

* 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 

을 분명히 충분히 : 역 추적 오류가 GLKTextureLoader의 자신의 작업자 스레드에서 발생하는 것을 보여주기 위해 나타납니다. 여기서 내가 뭘 잘못하고 있니?

화상이 메소드로 전달되는이 같은 것을 얻을 수있다 :

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]이 작동하고있는 것으로 보입니다. 어떤 아이디어?

+0

'이미지'는 어디에서 왔습니까? – borrrden

+0

@borrrden 질문을 세부 사항으로 업데이트했습니다. 늦은 답변 죄송합니다. – Stuart

+0

완료 블록에 다음 코드가 있습니다. if (completionHandler) completionHandler (textureName); 여기에 호출 된 completionHandler() 함수의 소스를 게시합니다. – idz

답변

2

이 항목을 처리하는 데 비동기 방법을 사용하고 있습니다. 릴리스를 수행하는 asyncLoader가 아닌 다른 것일 수 있습니다.

로컬로 UIImage로 이미지를 선언하고 실행하려면이 asyncLoader를 호출 한 다음 현재 호출하는 현재 메서드 인 현재의 stackFrame을 즉시 종료하면 전달한 UIImage가 이전에 릴리스되었을 가능성이 큽니다. asyncLoader에서 그걸 가지고 뭔가. (UIImage가 전달되고 호출 스택 프레임에서 해제되는 경우에도 같은 일이 발생합니다 ... 약한 경우 또는 asyncLoader가 실행되기 전에 약한 참조가 제거되면 제거됩니다).

나는 강력한 @property를 이미지 밖으로 만들고 (viewController의 viewDidUnload에서 nil로 설정)이 문제를 해결할 것을 제안합니다.

+0

'GLKTextureLoader' 인스턴스가 전달되는 이미지에 대한 참조를 강하게 포착하지 않았다면 놀랄 것입니다. 중요한 것은 주목할 점은'UIImage' 이 메소드에'CGImageRef'가 있는데, 이것에 대한 참조는 여전히'UIImage'에 의존하고 있습니다. 내 질문을 이미지 원본에 대해 좀 더 자세하게 업데이트 하겠지만 여기서는 이미지 참조 소유권과 관련된 오류가 맞다고 생각합니다. – Stuart

관련 문제