@autorelease指令和异常处理

发布于 2024-12-20 23:52:18 字数 466 浏览 3 评论 0原文

- (void)foo
{
    @try {
         for (id o in os){
             @autoreleasepool {
                 for (id o2 in moreOs){
                       // create a lot of autoreleased objects.
                 }
                //exception raised
            }
        }

    }
    @catch (NSException *exception) {
     // handle the exception   
    }
}
  1. 编译器会重写上述代码以在发生异常时耗尽池还是会泄漏?

  2. 如果编译器确实重写了它,它将如何做?

- (void)foo
{
    @try {
         for (id o in os){
             @autoreleasepool {
                 for (id o2 in moreOs){
                       // create a lot of autoreleased objects.
                 }
                //exception raised
            }
        }

    }
    @catch (NSException *exception) {
     // handle the exception   
    }
}
  1. Will the compiler rewrite the above code to drain the pool in the event of an exception or will it leak?

  2. If the compiler does rewrite it, how will it do it?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

软甜啾 2024-12-27 23:52:18

它不会不会排干游泳池的水。来自过渡ARC 发行说明

进入时,自动释放池被推送。在正常退出(中断、返回、转到、失败等)时,自动释放池会弹出。为了与现有代码兼容,如果由于异常而退出,则不会弹出自动释放池。

It will not drain the pool. From Transitioning to ARC Release Notes:

On entry, an autorelease pool is pushed. On normal exit (break, return, goto, fall-through, and so on) the autorelease pool is popped. For compatibility with existing code, if exit is due to an exception, the autorelease pool is not popped.

我纯我任性 2024-12-27 23:52:18

为了解决您的问题,在该池中创建的那些对象不会有效地泄漏,直到堆栈下方的一些自动释放池被耗尽。除了应用程序的主自动释放池之外,堆栈中可能没有其他池,该池可能在一段时间内不会被耗尽。

如果捕获到异常,请尝试执行以下操作,以强制在该方法返回时进行排空。

- (void)foo
{
    @autoreleasepool {
        @try {
            for (id o in os){
                @autoreleasepool {
                    for (id o2 in moreOs){
                        // create a lot of autoreleased objects.
                    }
                    //exception raised
                }
            }

        }
        @catch (NSException *exception) {
            // handle the exception   
        }
    }
}

根据文档,当最外面的自动释放池被耗尽时,它也会耗尽所有嵌套的自动释放池。

如果您排出的自动释放池不是堆栈顶部的,则堆栈上位于其上方的所有(未释放的)自动释放池都将被排出(并且它们的所有对象都发送了适当的释放消息)。如果您在完成自动释放池后忽略将排空发送到自动释放池(不推荐这样做),则当它嵌套的自动释放池之一被排空时,该池也会被排空。

来自 高级内存管理编程指南

To address your question, no those objects created in that pool will effectively be leaked until some autoreleasepool further down the stack is drained. There may be no pool further down the stack except the main autoreleasepool for your app which may not get drained for some time.

Try the following to force the drain to happen when this method returns if an exception is caught.

- (void)foo
{
    @autoreleasepool {
        @try {
            for (id o in os){
                @autoreleasepool {
                    for (id o2 in moreOs){
                        // create a lot of autoreleased objects.
                    }
                    //exception raised
                }
            }

        }
        @catch (NSException *exception) {
            // handle the exception   
        }
    }
}

According to documentation, when the outermost autoreleasepool is drained it will drain any nested ones as well.

If you drain an autorelease pool that is not the top of the stack, all (unreleased) autorelease pools above it on the stack are drained (and all their objects sent appropriate release messages). If you neglect to send drain to an autorelease pool when you are finished with it (something not recommended), the pool is drained when one of the autorelease pools in which it nests is drained.

From the "Scope of Autorelease Pools and Implications of Nested Autorelease Pools" section in Advanced Memory Management Programming Guide

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文