2013-01-01 1 views
6

가능한 가장 효율적인 방법으로 일부 핵심 이미지 필터를 실행하려고합니다. 큰 이미지를 렌더링 할 때 메모리 경고 및 충돌을 피하려고합니다. 나는 Apple의 Core Image Programming Guide를보고있다. 멀티 스레드에 관해서는 "각 스레드가 자체 CIFilter 객체를 만들어야하며, 그렇지 않으면 응용 프로그램이 예기치 않게 작동 할 수 있습니다."iOS : 코어 이미지 및 멀티 스레드 응용 프로그램

이것은 무엇을 의미합니까?

실제로 백그라운드 스레드에서 필터를 실행하려고하므로 기본 스레드에서 HUD를 실행할 수 있습니다 (아래 참조). 이것은 coreImage의 맥락에서 의미가 있습니까? 핵심 이미지가 본질적으로 GCD를 사용한다는 것을 모았습니다. 애플 문서에서

//start HUD code here, on main thread 

// Get a concurrent queue form the system 
dispatch_queue_t concurrentQueue = 
dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
dispatch_async(concurrentQueue, ^{ 

    //Effect image using Core Image filter chain on a background thread 

    dispatch_async(dispatch_get_main_queue(), ^{ 

     //dismiss HUD and add fitered image to imageView in main thread 

    }); 

}); 

더 :

스레드로부터의 안전성을

CIContext 및 CIImage 객체를 유지는 각 스레드간에 안전하게 공유 할 수있는 의미, 을 변경할 수 있습니다. 다중 스레드 은 동일한 GPU 또는 CPU CIContext 객체를 사용하여 CIImage 객체를 렌더링 할 수 있습니다. 그러나 이것은 변경 가능한 CIFilter 오브젝트의 경우에는 해당되지 않습니다. CIFilter 객체는 스레드간에 안전하게 공유 할 수 없습니다. 응용 프로그램이 다중 스레드 인 경우 각 스레드는 고유 한 CIFilter 개체를 만들어야합니다. 그렇지 않으면 앱이 예기치 않게 작동 할 수 있습니다.

답변

11

어떻게 다르게 말할 지 모르겠습니다. 각 배경 스레드는 필터 체인에 자체 CIFilter 개체 버전을 만들어야합니다. 이를 달성하는 한 가지 방법은 모든 백그라운드 작업에 대한 필터 체인의 복사본을 만드는 것입니다. dispatch_async(...). 여기 일이 filterForThreadmyFilter의 사본입니다 무엇

//start HUD code here, on main thread 
// Assuming you already have a CIFilter* variable, created on the main thread, called `myFilter` 
CIFilter* filterForThread = [myFilter copy]; 
// Get a concurrent queue form the system 
dispatch_queue_t concurrentQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); 
dispatch_async(concurrentQueue, ^{ 
    CIFilter filter = filterForThread; 

    // Effect image using Core Image filter chain on a background thread 

    dispatch_async(dispatch_get_main_queue(), ^{ 

     //dismiss HUD and add fitered image to imageView in main thread 

    }); 

}); 
[filterForThread release]; 

:이 같은 것을 보일 수 있습니다 뭔가를 게시 한 코드에서. dispatch_async에 전달하는 블록에서 filterForThread을 참조하면 해당 블록이 filterForThread을 보유하게되고 호출 범위에서 filterForThread이 해제되어 filterForThread의 개념적 소유권이 블록으로 전송되는 것을 효과적으로 완료합니다 (블록이 참조로 남아있는 유일한 블록이기 때문에). 그것). filterForThread은 블록이 실행되는 스레드에 대해 개인용으로 간주 될 수 있습니다.

여기는 스레드 안전 요구 사항을 충족시키기에 충분해야합니다.

+0

감사합니다. 나는 당신의 대답을 몇 십 번 읽고 어쩌면 그것은 :)에 가라 앉을 것이다. – Mrwolfy

+1

다음과 같은 유추가 있습니다. 종이를 쓰고 있고 5 명의 사람들이 동시에 (동시에) 검토/편집하기를 원한다면 한 장의 인쇄물을 만들지 않고 그 주위에 5 명을 배치하고 그들은 동시에 편집을 시도합니다. 5 부씩 작성하고 각 리뷰어/편집자에게 각자의 사본을 제공하십시오. 여기 같은 생각. 각 스레드에게 CIFilter의 자체 복사본을 제공합니다. – ipmcc

+0

괜찮습니다. 도와 주셔서 감사합니다. – Mrwolfy