gpt4 book ai didi

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

转载 作者:可可西里 更新时间:2023-11-01 03:28:33 27 4
gpt4 key购买 nike

我正在尝试以最有效的方式运行一些核心图像过滤器。试图避免内存警告和崩溃,这是我在渲染大图像时遇到的。我正在看 Apple 的 Core Image Programming Guide。关于多线程,它说:“每个线程都必须创建自己的 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 文档:

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, 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 的 block 中引用 filterForThread 将导致该 block 保留 filterForThread,然后调用作用域释放 filterForThread,这有效地完成了将 filterForThread 的概念所有权转移到 block (因为 block 是唯一留下对它的引用的东西)。 filterForThread 可以被认为是执行 block 的线程私有(private)的。

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

关于iOS:核心图像和多线程应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14109671/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com