简体   繁体   English

什么时候我应该将我的代码包装到自动释放池中

[英]when should I wrap my code into autorelease pool

I am a new to objective-c, and I know the basic memory management rules like when to retain release autorelease . 我是objective-c的新手,我知道基本的内存管理规则,比如什么时候retain release autorelease But I don't know when should I wrap my code into autorelease pool and why? 但是我不知道什么时候应该将代码包装到自动释放池中?为什么?

As with other performance optimizations, you should generally only add additional autorelease pools to your code if you notice high memory usage and profiling (using Instruments, for example) leads you to additional autorelease pools as a solution. 与其他性能优化一样,如果您注意到内存使用率很高,通常只应向代码中添加其他自动释放池,例如,使用Instruments会导致您将其他自动释放池作为解决方案。

That said, you can wrap code that creates a large number of temporary objects in a tight loop in an autorelease pool. 也就是说,您可以在自动释放池中的紧密循环中包装创建大量临时对象的代码。 The default autorelease pool is drained at the end of a run loop cycle. 默认自动释放池在运行循环周期结束时耗尽。 So, if you're creating lots of temporary objects in each iteration of a for loop in your code, the default autorelease pool won't be drained until after your entire loop has run, meaning all the temporary objects you create can add up to a high temporary memory usage (sometimes called the "high water mark"). 因此,如果您在代码中的for循环的每次迭代中创建了大量临时对象,则默认自动释放池将在整个循环运行之后才会耗尽,这意味着您创建的所有临时对象都可以累加到高临时内存使用率(有时称为“高水位线”)。 You can wrap each iteration of the loop in an @autoreleasepool to cause unneeded, autoreleased, temporary objects created in that loop iteration to be released sooner. 您可以将循环的每个迭代包装在@autoreleasepool以使得在该循环迭代中创建的不需要的,自动释放的临时对象更快地被释放。

To extends the previous answers: 扩展以前的答案:

An auto-release pool is used to send a release message automatically to objects added to it. 自动释放池用于自动向添加到其中的对象发送release消息。

In a iOS or Cocoa program, an auto-release pool is automatically created on the main thread, and it's drained at the end of the run loop. 在iOS或Cocoa程序中,会在主线程上自动创建自动释放池,并在运行循环结束时将其耗尽。

That said, an auto-release pool is mandatory when using auto-released objects on another thread. 也就是说,在另一个线程上使用自动释放的对象时,必须使用自动释放池。

So if you detach a thread to some method, then wrap your threaded code inside an auto-release pool. 因此,如果将线程分离到某个方法,则将线程代码包装在自动释放池中。 Otherwise, the auto-released objects created in the thread will just leak. 否则,线程中创建的自动释放对象将泄漏。

Another use of an auto-release pool is the optimization of parts of code that will use a lot of memory, so they are freed before the end of the run loop. 自动释放池的另一个用途是优化将使用大量内存的代码部分,因此它们在运行循环结束之前被释放。

But it only concerns auto-released objects. 但它只涉及自动发布的对象。

For instance: 例如:

- ( void )test
{
    NSMutableArray * a = [ [ NSMutableArray alloc ] init ];

    [ a release ];
}

No need for an auto-release pool here, as you don't have an auto-released object. 这里不需要自动释放池,因为您没有自动释放的对象。
The a variable will be freed immediately, as it was explicitly allocated, and released. a变量将被立即释放,因为它已被明确分配并释放。

Now this: 现在这个:

- ( void )test
{
    NSMutableArray * a = [ NSMutableArray arrayWithCapacity ];
}

Here you are using a convenience constructor, meaning you don't have the ownership on that object. 在这里,您使用的是便利构造函数,这意味着您没有该对象的所有权。
It also means the object was added to the current auto-release pool (if there's one). 它还意味着该对象已添加到当前自动释放池(如果有的话)。

So it will be freed when this auto-release pool is drained, so it might take some cycles... 因此,当此自动释放池耗尽时,它将被释放,因此可能需要一些周期......

If the portion of the code you are writing uses a lot of memory, you may use another auto-release pool, so your auto-released objects are freed when your method returns: 如果您编写的代码部分使用大量内存,则可以使用另一个自动释放池,以便在方法返回时释放自动释放的对象:

- ( void )test
{
    @autoreleasepool
    {
        NSMutableArray * a = [ NSMutableArray arrayWithCapacity ];
    }
}

All autoreleased objects are technically put inside an autorelease pool. 从技术上讲,所有自动释放的对象都放在自动释放池中。 There is usually a default one created inside your main function. 通常在主函数内部创建一个默认值。 As for wrapping objects within a non-default autorelease pool, that is usually done as an optimization. 至于在非默认自动释放池中包装对象,通常将其作为优化来完成。

There is usually no need to use an explicit autorelease pool because the default autorelease pool is drained automatically within your app's run loop. 通常不需要使用显式自动释放池,因为默认的自动释放池会在应用程序的运行循环中自动排出。 However, if you have an app that creates many autoreleased objects before it returns from your event handlers, it can use a lot of memory for those objects. 但是,如果您的应用程序在从事件处理程序返回之前创建了许多自动释放的对象,则它可以为这些对象使用大量内存。 So if you wrap your code inside an explicit autorelease pool, the autoreleased objects will be placed there rather than the default pool. 因此,如果将代码包装在显式自动释放池中,则自动释放的对象将放在那里而不是默认池中。 This allows you to periodically empty this pool to prevent the autoreleased objects from accumulating. 这允许您定期清空此池以防止自动释放的对象累积。

There are, however, three occasions when you might use your own autorelease pool blocks: 但是,有三种情况可能会使用您自己的自动释放池块:

  1. If you are writing a program that is not based on a UI framework, such as a command-line tool. 如果您正在编写不基于UI框架的程序,例如命令行工具。

  2. If you write a loop that creates many temporary objects. 如果编写一个创建许多临时对象的循环。 You may use an autorelease pool block inside the loop to dispose of those objects before the next iteration. 您可以在循环内使用自动释放池块在下一次迭代之前处理这些对象。 Using an autorelease pool block in the loop helps to reduce the maximum memory footprint of the application. 在循环中使用自动释放池块有助于减少应用程序的最大内存占用量。

  3. If you spawn a secondary thread. 如果你产生一个辅助线程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM