iOS:核心图像和多线程应用程序

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

这是什么意思?

我实际上是试图在后台线程上运行我的过滤器,所以我可以在主线程上运行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:

Maintaining Thread Safety

CIContext and CIImage objects are immutable,
which means each can be shared safely among threads. Multiple threads
can use the same GPU or cpu CIContext object to render CIImage
objects. However,this is not the case for CIFilter objects,which are
mutable. A CIFilter object cannot be shared safely among threads. If
your app is multithreaded,each thread must create its own CIFilter
objects. Otherwise,your app Could behave unexpectedly.

解决方法

我不确定如何区别对待:每个后台线程都需要在过滤器链中创建自己的CIFilter对象版本.实现此目的的一种方法是为dispatch_async(…)的每个后台操作制作过滤器链的副本.在您发布的代码中,可能看起来像这样:
//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,^{
    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];

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

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

相关文章

UITabBarController 是 iOS 中用于管理和显示选项卡界面的一...
UITableView的重用机制避免了频繁创建和销毁单元格的开销,使...
Objective-C中,类的实例变量(instance variables)和属性(...
从内存管理的角度来看,block可以作为方法的传入参数是因为b...
WKWebView 是 iOS 开发中用于显示网页内容的组件,它是在 iO...
OC中常用的多线程编程技术: 1. NSThread NSThread是Objecti...