많은 문자열 (문자열)을 만들고로드하고 있습니다. 애니메이션이 원활하게 실행되도록하기 위해 작업을 별도의 작업자 스레드로 오프로드합니다. 그것은 내가 원하는 방식으로 다소 정확하게 작동하는 것으로 보이지만 오래된 장치 (iPhone 3GS)에서는 때로는 긴 (1 초) 지연을 느낍니다. 때때로 발생합니다. 이제 내가 제대로하고 있는지 또는 개념적으로 문제가 있는지 궁금합니다. 아래에 소스 코드를 붙여 넣습니다.비동기 텍스처로드 iPhone OpenGL ES 2
또한 GLKit TextureLoader를 사용하고 싶지 않습니다. 왜냐하면로드하는 부분뿐만 아니라 다른 스레드에 텍스처 생성 작업을 오프로드하기를 원하기 때문입니다. http://youtu.be/U03p4ZhLjvY?hd=1
NSLock* _textureLock;
NSMutableDictionary* _texturesWithString;
NSMutableArray* _texturesWithStringLoading;
// This is called when I request a new texture from the drawing routine.
// If this function returns 0, it means the texture is not ready and Im not displaying it.
-(unsigned int)getTextureWithString:(NSString*)string {
Texture2D* _texture = [_texturesWithString objectForKey:string];
if (_texture==nil){
if (![_texturesWithStringLoading containsObject:string]){
[_texturesWithStringLoading addObject:string];
NSDictionary* dic = [[NSDictionary alloc] initWithObjectsAndKeys:string,@"string", nil];
NSThread* thread = [[NSThread alloc] initWithTarget:self selector:@selector(loadTextureWithDictionary:)object:dic];
thread.threadPriority = 0.01;
[thread start];
[thread release];
}
return 0;
}
return _texture.name;
}
// This is executed on a separate worker thread.
// The lock makes sure that there are not hundreds of separate threads all creating a texture at the same time and therefore slowing everything down.
// There must be a smarter way of doing that. Please let me know if you know how! ;-)
-(void)loadTextureWithOptions:(NSDictionary*)_dic{
[_textureLock lock];
EAGLContext* context = [[SharegroupManager defaultSharegroup] getNewContext];
[EAGLContext setCurrentContext: context];
NSString* string = [_dic objectForKey:@"string"];
Texture2D* _texture = [[Texture2D alloc] initWithStringModified:string];
if (_texture!=nil) {
NSDictionary* _newdic = [[NSDictionary alloc] initWithObjectsAndKeys:_texture,@"texture",string,@"string", nil];
[self performSelectorOnMainThread:@selector(doneLoadingTexture:) withObject:_newdic waitUntilDone:NO];
[_newdic release];
[_texture release];
}
[EAGLContext setCurrentContext: nil];
[context release];
[_textureLock unlock];
}
// This callback is executed on the main thread and marks adds the texture to the texture cache.
-(void)doneLoadingTextureWithDictionary:(NSDictionary*)_dic{
[_texturesWithString setValue:[_dic objectForKey:@"texture"] forKey:[_dic objectForKey:@"string"]];
[_texturesWithStringLoading removeObject:[_dic objectForKey:@"string"]];
}
질문을 게시 한 직후와 마찬가지로 정상적으로 작동합니다. 이제는 너무 많은 NSThread를 생성하지 않고 NSOperationQueue를 사용합니다. 그게 문제를 해결할 것 같다 'maxConcurrentOperationCount'를 설정할 수 있습니다. 나는 내가 너에게 어리석은 다른 것을하고 있는지 아직도 듣고 싶다. – hanno
리소스 제한 문제가있는 경우 디스패치 세마포를 살펴보십시오. http://www.mikeash.com/pyblog/friday-qa-2009-09-25-gcd-practicum.html. 나는 I/O 속도가 처리 속도보다 더 제한적일 수있는 이와 같은 항목에 일반적으로이를 사용합니다. –
감사합니다. 다른 것 : 공유 그룹에서 새 컨텍스트를 가져오고 설정하는 데는 도구에 따라 많은 시간이 필요합니다. 추가 컨텍스트 중 하나를 작성하고 스레드간에 재사용해야합니까? 한 번에 하나의 스레드에서만 액세스 할 수 있도록해야합니까? 나는 어딘가에서 내가 그렇게해서는 안되는 것을 기억하는 이유를 기억하지 못한다. – hanno