iOS:核心图像和multithreading应用程序

我试图以最有效的方式运行一些核心图像filter。 试图避免内存警告和崩溃,这是我在渲染大图像时得到的。 我正在看Apple的核心图像编程指南。 关于multithreading,它说: “每个线程必须创建自己的CIFilter对象。否则,你的应用程序可能会出现意外行为。”

这是什么意思?

我实际上是试图在后台线程上运行我的filter,所以我可以在主线程上运行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 }); }); 

更多来自Apple Docs:

保持线程安全

CIContext和CIImage对象是不可变的,这意味着每个对象都可以在线程之间安全地共享。 多个线程可以使用相同的GPU或CPU CIContext对象来呈现CIImage对象。 但是,对于可变的CIFilter对象,情况并非如此。 无法在线程之间安全地共享CIFilter对象。 如果您的应用程序是multithreading的,则每个线程都必须创建自己的CIFilter对象。 否则,您的应用可能会出现意外行为。

我不确定如何区别对待:每个后台线程都需要在filter链中创建自己的CIFilter对象版本。 实现此目的的一种方法是为dispatch_async(...)每个后台操作制作filter链的副本。 在您发布的代码中,可能看起来像这样:

 //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]; 

这里发生的是filterForThreadmyFilter的副本。 在传递给dispatch_async的块中引用filterForThread将导致该块保留filterForThread ,然后调用范围释放filterForThread ,这有效地完成了filterForThread对块的概念所有权的转移(因为块是唯一留下引用的块)它)。 filterForThread可以被认为是执行块的线程的私有。

这应该足以满足此处的线程安全要求。