iOS:核心图像和多线程应用程序 [英] iOS: Core image and multi threaded apps
问题描述
我试图以最有效的方式运行一些核心图像过滤器。试图避免内存警告和崩溃,这是我在渲染大图像时得到的。我正在看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屋!