iOS:核心图像和多线程应用程序 [英] iOS: Core image and multi threaded apps

查看:92
本文介绍了iOS:核心图像和多线程应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I am trying to run some core image filters in the most efficient way possible. Trying to avoid memory warnings and crashes, which I am getting when rendering large images. I am looking at Apple's Core Image Programming Guide. Regarding multi-threading it says: "each thread must create its own CIFilter objects. Otherwise, your app could behave unexpectedly."

什么这意味着什么?

我实际上是在尝试在后台线程上运行我的过滤器,所以我可以在主线程上运行HUD(见下文)。这在coreImage的上下文中是否有意义?我认为核心图像固有地使用GCD。

I am in fact attempting to run my filters on a background thread, so I can run an HUD on the main thread (see below). Does this make sense in the context of coreImage? I gather that core image inherently uses 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的更多内容:

More from the Apple Docs:


维护线程安全

Maintaining Thread Safety

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

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(...)的每个后台操作制作过滤器链的副本。在您发布的代码中,可能看起来像这样:

I'm not sure how to say it differently: Each background thread needs to create it's own version of the CIFilter objects in your filter chain. One way to achieve this would be to make a copy of your filter chain for every background operation you dispatch_async(...). In the code that you posted that might look something like this:

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

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

What happens here is that filterForThread is a copy of myFilter. Referencing filterForThread in the block you pass to dispatch_async will cause that block to retain filterForThread, then the calling scope releases filterForThread, which effectively completes the transfer of conceptual ownership of filterForThread to the block (since the block is the only thing left with a reference to it). filterForThread can be thought of as private to the thread where the block is executed.

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

That should be enough to satisfy the thread safety requirements here.

这篇关于iOS:核心图像和多线程应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆