菜鸟教程小白 发表于 2022-12-13 15:28:50

ios - @try-@finally 确保在处理未被 ARC 跟踪的对象时消除内存泄漏


                                            <p><p>假设我们使用 <code>malloc()/calloc()</code> 手动分配内存或分配一些未被 ARC 跟踪的对象(如 <code>CGContextRef</code>)。然后,我们正在做一些事情。最终,我们需要释放该内存。</p>

<p>例子:</p>

<pre><code>void *buf = NULL;   // malloc() allocated object example
CGContextRef context; // Non-manageable by ARC object example

@try {
    buf = malloc(bufSize);
    context = CGBitmapContextCreate(buf, width, height, bitsPerComponent, bytesPerRow, colorSpace, kCGImageAlphaNone);

    // Some exception-prone stuff is going here
}
@catch (NSException *e) {
    // ...
}
@finally {
    CGContextRelease(context);
    free(buf);
}
</code></pre>

<p>在@try-@finally 中进行内存分配/取消分配是保证在“do stuff”部分抛出异常时释放它的最佳/正确/推荐方法吗?</p >

<p>如果不是,您能否建议一种更好的技术并解释为什么它更可取?</p></p>
                                    <br><hr><h1><strong>Best Answer-推荐答案</ strong></h1><br>
                                            <p><blockquote>
<p>Is putting a memory allocation/de-allocation in a @try-@finally the best/proper/recommended approach to guarantee that it would be freed in case if exception is thrown in the &#34;do stuff&#34; section?</p>
</blockquote>

<p>没有。</p>

<p>ObjC 异常应该总是会在不久的将来导致崩溃。从 <code>@try</code> 完全恢复是不好的 ObjC;最终你应该总是重新抛出异常以允许程序崩溃。您的问题实际上有点倒退,担心非ARC管理的对象。除非您编译为 ObjC++,否则 ARC 会在 ObjC 异常后故意像筛子一样泄漏。</p>

<p>正确的做法是消除异常。在 ObjC 中不应该有“一些容易发生异常的东西在这里发生”之类的东西。 ObjC 不是(也从未打算成为)异常安全的语言。当编译为 ObjC++ 时,需要完成额外的工作(以及额外的运行时开销)以尝试使其更安全,因为 C++ 异常很常见,但这不应被视为使用 <code>@try</code> 的理由>.</p>

<p> <a href="http://clang.llvm.org/docs/AutomaticReferenceCounting.html#exceptions" rel="noreferrer noopener nofollow">Clang&#39;s explanation of ARC with exceptions</a>是该主题的出色入门读物。最有启发性的是本节(强调添加):</p>

<blockquote>
<p><strong>The standard Cocoa convention is that exceptions signal programmer error and are not intended to be recovered from.</strong> Making code exceptions-safe by default would impose severe runtime and code size penalties on code that typically does not actually care about exceptions safety. Therefore, ARC-generated code leaks by default on exceptions, which is just fine if the process is going to be immediately terminated anyway. Programs which do care about recovering from exceptions should enable the option.</p>
</blockquote>

<p>还有<a href="https://developer.apple.com/library/content/documentation/Cocoa/Conceptual/Exceptions/Articles/ExceptionsAndCocoaFrameworks.html#//apple_ref/doc/uid/TP40009045-SW1" rel="noreferrer noopener nofollow">Exception Programming Topics</a> :</p>

<blockquote>
<p>The Cocoa frameworks are generally not exception-safe. The general pattern is that exceptions are reserved for programmer error only, and the program catching such an exception should quit soon afterwards.</p>
</blockquote>

<p>使用 <code>@catch</code> 的唯一原因是因为您想创建某种诊断程序来帮助您了解崩溃(正确地执行此操作是一个非常高级的主题,不适合微弱的人)心或新手)。它绝不是为了将您从编程错误中解救出来。</p>

<p>请注意,ObjC 的 <code>@try</code> 与 Swift 的 <code>try</code> 完全无关。 Swift 的 <code>try</code> 只是一个花哨/神奇的 <code>return</code> (它甚至不是其他语言中通常表示的“异常”)。</p></p>
                                   
                                                <p style="font-size: 20px;">关于ios - @try-@finally 确保在处理未被 ARC 跟踪的对象时消除内存泄漏,我们在Stack Overflow上找到一个类似的问题:
                                                        <a href="https://stackoverflow.com/questions/44659503/" rel="noreferrer noopener nofollow" style="color: red;">
                                                                https://stackoverflow.com/questions/44659503/
                                                        </a>
                                                </p>
                                       
页: [1]
查看完整版本: ios - @try-@finally 确保在处理未被 ARC 跟踪的对象时消除内存泄漏