微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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可以被认为是执行块的线程的私有.

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐