菜鸟教程小白 发表于 2022-12-12 22:39:15

objective-c - iOS 编程自动释放池


                                            <p><p>在 <a href="https://developer.apple.com/library/ios/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html" rel="noreferrer noopener nofollow">Apple documentation</a> ,它说:</p>

<blockquote>
<p>The AppKit and UIKit frameworks process each event-loop iteration
(such as a mouse down event or a tap) within an autorelease pool
block. Therefore you typically do not have to create an autorelease
pool block yourself, or even see the code that is used to create one.</p>
</blockquote>

<p>现在,这应该是显而易见的,但无论如何我都会要求确认。</p>

<p>如果我正在开发最终将成为后台进程的内容(通过 Grand Central Dispatch),但为简单起见,我首先将其放在第一个加载 View 的 viewDidLoad 中,这样我的 View 实际上不会显示在屏幕直到所有(比如说)2分钟的处理完成,然后在这两分钟内所有默认的自动释放池永远不会被释放,因为它还没有通过事件循环迭代,对吧?听到拒绝简直是疯了,但我陷入了这个日益严重的内存问题,所以我会要求确认并希望有一个好消息。</p>

<p>如果是这样,我应该放置我自己的自动释放 block 。如果处理是通过 GCD 在后台进程中完成的,我仍然需要自动释放 block ,对吗? </p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><p>我会尽力为您提供两个问题的完整答案。</p>

<p>第一部分。首先要注意主线程中长时间运行的操作。例如,如果您的操作需要两分钟,则主线程将被阻塞,直到它完成。从用户的角度来看,应用程序将在两分钟内没有响应。
无论如何,是的,在应用程序委托(delegate)中有一个插入自动释放对象的池。当循环结束时,池内的对象会被释放,因为池会自动排空。
如果您有内存问题,可以查看 <a href="http://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html#//apple_ref/doc/uid/20000047-CJBFBEDI" rel="noreferrer noopener nofollow">Use Local Autorelease Pool Blocks to Reduce Peak Memory Footprint</a> .如文档中所写,您应该将操作包装在自动释放 block 中。在 block 结束时,临时对象被释放,这通常会导致它们的释放,从而减少程序的内存占用。</p>

<p>关于 GCD 问题,我会说不。处理 GCD 时不必创建自动释放池。通常,也写在 <a href="https://stackoverflow.com/questions/4141123/do-you-need-to-create-an-nsautoreleasepool-within-a-block-in-gcd" rel="noreferrer noopener nofollow">Do you need to create an NSAutoreleasePool within a block in GCD?</a> , GCD 自动管理每个队列的自动释放池。所以,如果你的对象很少,你不必担心,但如果你创建了很多,是的,创建一个自动释放池。后者还可以让您减少内存占用。</p>

<blockquote>
<p>So for this entire two minutes where the app will not be responsive,
it is when the loop has not ended, and the pool is not drained during
these two minutes, right?</p>
</blockquote>

<p>应用程序没有响应,因为主线程(通过运行循环)按顺序执行任务。如果您阻止运行循环,应用程序会卡住,直到长时间运行的操作完成(我认为如果您超过特定时间段,应用程序会被 iOS 杀死)。为避免这种情况,您可以(如您所写)在不同的线程中执行长时间运行的操作。</p>

<p>使用线程的目的是使应用程序具有高响应性,但它​​可能会导致各种问题,例如不一致的数据(<em>竞争条件</em>)或<em>死锁</em>。</p>

<p>我真的建议阅读更多信息 <a href="http://bynomial.com/blog/?p=15" rel="noreferrer noopener nofollow">The pogo stick of NSRunLoop</a> , <a href="https://stackoverflow.com/questions/12091212/understanding-nsrunloop" rel="noreferrer noopener nofollow">Understanding NSRunLoop</a>和 <a href="https://stackoverflow.com/questions/7222449/nsdefaultrunloopmode-vs-nsrunloopcommonmodes" rel="noreferrer noopener nofollow">NSDefaultRunLoopMode vs NSRunLoopCommonModes</a> .</p></p>
                                   
                                                <p style="font-size: 20px;">关于objective-c - iOS 编程自动释放池,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/12218949/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/12218949/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: objective-c - iOS 编程自动释放池