菜鸟教程小白 发表于 2022-12-13 14:26:26

objective-c - iOS自动线程?


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

<pre><code>- (IBAction)play_pause:(id)sender
{
play = !play;
while(play)
{
    if (_videoCapture &amp;&amp; _videoCapture-&gt;grab())
    {
      (*_videoCapture) &gt;&gt; _display_frame;
      //process frame
      self.imageView.image = ;
    }
}
}
</code></pre>

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

<p>旁注-</p>

<p>最终让我调查的是 返回一个自动释放的对象。由于所有这些都发生在一个循环内,因此如果不暂停执行,就无法释放对象,这会导致崩溃。 </p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>之所以成功,是因为 <code>cv::VideoCapture::grab()</code> 方法的实现会运行当前的 run loop 来暂停线程,直到它得到一帧。</p>

<p>当您启动应用程序时,<code>main</code> 函数会执行名为 <code>UIApplicationMain</code> 的函数,该函数会执行 <code>CFRunLoopRun</code>。当 <code>CFRunLoopRun</code> 在主线程上执行时,它会运行主运行循环,即处理从系统接收到的所有 UI 事件并刷新用户界面的运行循环。有关运行循环的信息,您可以阅读 <a href="https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/Multithreading/RunLoopManagement/RunLoopManagement.html#//apple_ref/doc/uid/10000057i-CH16-SW1" rel="noreferrer noopener nofollow">Apple Threading Programming Guide</a> .</p>

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

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

<p>主函数→运行循环→事件处理→您的代码→OpenCV→运行循环→事件处理→您的代码</p>

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

<p>但我不确定 OpenCV 的开发人员在编写代码时是否考虑到了这一点。所以我认为将帧加载到后台线程/队列中会更好。</p></p>
                                   
                                                <p style="font-size: 20px;">关于objective-c - iOS自动线程?,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/11194058/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/11194058/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: objective-c - iOS自动线程?