2012-01-03 2 views
4

다소 느린 (100-200ms) drawRect 메서드가 있습니다. 시간을 절약하기 위해 결과를 캐시해야합니다. 실제 캐시를 다음과 같이 수행하고 있습니다.기본 스레드에서 우선 순위가 낮은 작업 예약

// some code to check if caching would be desirable goes here. If it is desirable, then 
UIGraphicsBeginImageContext(viewSize); 
CGContextRef c = UIGraphicsGetCurrentContext(); 
[view.layer renderInContext: c]; 
UIImage* image = UIGraphicsGetImageFromCurrentImageContext(); 
[self.cachedImageArray addObject:image]; 
UIGraphicsEndImageContext(); 

캐싱 자체에는 최대 40ms가 걸릴 수 있습니다. 이것은 여전히 ​​쉽게 가치가 있습니다. 그러나 캐싱은 모든 것이 렌더링되거나 오류가 발생할 때까지 기다려야합니다. 또한 캐싱은 우선 순위가 낮은 작업입니다. 일단 모든 것이 표시되면 다른 일들이 계속 될 가능성이 있으며, 그렇다면 캐싱을 기다릴 수 있습니다. 하지만 UIKit을 사용하기 때문에 메인 스레드에 있어야합니다.

임의의 지연을 적용하는 대신, 이렇게 기다리는 방탄 방법이 있습니까?

+2

왜 캐싱 작업이 주 스레드에 있어야합니까? 'performSelectorOnMainThread' 또는 GCD의 magic'dispatch_async (dispatch_get_main_queue(),^{}); '를 통해 주 스레드에서 결과를 보내거나 표시 할 수 없었습니다. 마지막에 다른 스레드에서 캐싱을 시작합니다. 당신의'drawRect'는 무엇입니까? –

+3

그래픽 콘텍스트에 드로잉하는 것은 iOS 4만큼이나 스레드 세이프이며 메인 스레드에서 수행 할 필요는 없습니다.이 모든 것을'dispatch_async() '를 사용하여 백그라운드 스레드로 넘길 수 있습니다 .. –

답변

1

캐싱 자체는 주 스레드에서 수행 할 필요가 없습니다. 이미지 컨텍스트 또는 비트 맵 데이터의 복사/참조를 가져올 수 있으며 렌더링이 완료 될 때만 NSThread를 사용하여 시작할 수 있습니다. 예 :

- (void) drawRect:(CGRect)rect { 
    do_rendering_here(); 
    // when rendering completed: 
    NSThread *t = [[NSThread alloc] initWithTarget:self selector:@selector(doCaching:) object:c]; 
    [t start]; 
    [t release]; 
} 

- (void) doCaching:(CGContextRef)ctx { 
    // do whatever kind of caching is needed 
} 
+0

USing 'NSThread는 여전히 허용되지만 Apple은 대부분의 작업에서이 작업을 권장합니다. Grand Central Dispatch를 사용하고 질문에 대한 그의 의견에서 @ MichaelDautermann의 솔루션을 사용하는 것이 훨씬 더 낫습니다. Apple의 동시성 가이드 (http://developer.apple.com/)를 확인하십시오. –

+0

죄송합니다. iOS5를 사용할 수있는 기기를 소유하고 있지 않기 때문에이 새로운 API를 사용할 수 없으며 다른 API도 제공하지 않습니다. 3.1.3 헤더에서 빌드 된 오래된 툴체인 ... –

+1

@ H2CO3 - GCD는 iOS 4.0과 함께 제공되었으므로 잠시 후 지원되었습니다. 또한 백그라운드 스레드에서 무언가를 수행하기 위해 NSThread 인스턴스를 복잡한 위치에 할당 할 필요가 없습니다. NSObject의'-performSelectorInBackground : withObject :'를 사용하기 만하면됩니다. –