gpt4 book ai didi

objective-c - iOS自动线程?

转载 作者:塔克拉玛干 更新时间:2023-11-02 10:15:07 32 4
gpt4 key购买 nike

我一直在为 iOS 开发一个 opencv 项目。我得到了一个简单的项目,可以开始使用捕获和显示的帧进行开发。在我开始遇到内存问题并将它们追溯到原始项目设置之前,我从来没有过多关注它是如何工作的。我现在计划重新编写捕获/显示代码,但我不明白为什么它首先起作用。有一个调用该方法的播放/暂停按钮

- (IBAction)play_pause:(id)sender
{
play = !play;
while(play)
{
if (_videoCapture && _videoCapture->grab())
{
(*_videoCapture) >> _display_frame;
//process frame
self.imageView.image = [UIImage imageWithCVMat:_display_frame];
}
}
}

play 只是一个全局 bool 值,表示应用程序是正在播放还是暂停。奇怪的是,处理应该在无限循环中进行,没有出路。 play 永远不会在循环中被修改。尽管如此,当应用程序正在运行时,播放/暂停按钮仍保持响应,并且能够翻转播放按钮并暂停执行。不仅如此,其他 bool 值(例如 use_greyscale)可以被其他按钮翻转,并且它们的值在循环内发生变化。我本以为应用程序会卡住,甚至不会在屏幕上绘制新帧。应用程序在其生命周期的大部分时间里都应该被困在该函数中,无法执行其他任务,例如绘图和 UIControl。似乎唯一可行的方法是 IBAction 调用在其自己的线程上运行。我在源代码中找不到任何线程的证据。有人可以解释苹果如何处理其 UI 中的线程吗?我的印象是只有一个主运行循环线程,并且不会自动创建额外的线程。如果这是真的,如何解释这种行为?

边注-

最终让我对此进行调查的是 [UIImage imageWithCVMat:_display_frame] 返回一个自动释放的对象。由于所有这些都发生在一个循环内,因此如果不暂停执行,则无法释放对象,这会导致崩溃。

最佳答案

之所以有效,是因为 cv::VideoCapture::grab() 方法的实现运行当前运行循环以暂停线程,直到它获得帧。

当您启动应用程序时,main 函数会执行名为 UIApplicationMain 的函数,该函数会执行 CFRunLoopRun。当 CFRunLoopRun 在主线程上执行时,它运行主运行循环,这是处理从系统接收到的所有 UI 事件并刷新用户界面的运行循环。有关运行循环的信息,您可以阅读 Apple Threading Programming Guide .

因此,当您执行无限循环时,您的代码永远不会返回到运行循环,并且无法处理等待事件。但在您的情况下, grab 方法会再次运行运行循环,但会延迟到期。因此 run loop 可能会处理传入的事件(可能会再次调用您的代码)直到延迟到期,然后返回将再次运行 run loop 的代码。

如果您在触摸按钮暂停时查看调用堆栈,您会看到:

主函数 → 运行循环 → 事件处理 → 你的代码 → OpenCV → 运行循环 → 事件处理 → 你的代码

运行循环在自身内部运行,这非常好,因为运行循环是可重入的。 ScrollView 实际上使用了该行为:当您滚动 UIScrollView 时,它会以不同的模式再次运行运行循环,以便在您结束滚动之前忽略一些事件。

但我不确定 OpenCV 的开发人员在编写代码时是否考虑到了这一点。所以我认为最好在后台线程/队列中加载您的帧。

关于objective-c - iOS自动线程?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11194058/

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