Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 9230987
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: June 18, 20262026-06-18T05:57:26+00:00 2026-06-18T05:57:26+00:00

I’m interested in learning more about how best to handle memory management under tight

  • 0

I’m interested in learning more about how best to handle memory management under tight loops with ARC. In particular, I’ve got an app I’m writing which has a while loop which rus for a really long time, and I’ve noticed that despite having implemented (what I believe to be) the best practices in ARC, the heap keeps growing boundlessly.

To illustrate the problem I’m having, I first set up the following test to fail on purpose:

while (true) {         
    NSMutableArray *array = [NSMutableArray arrayWithObject:@"Foo"];
    [array addObject:@"bar"]; // do something with it to prevent compiler optimisations from skipping over it entirely
}

Running this code and profiling with the Allocations tool shows that the memory usage just endlessly increases. However, wrapping this in an @autoreleasepool as follows, immediately resolves the issue and keeps the memory usage nice and low:

while (true) {
    @autoreleasepool {         
        NSMutableArray *array = [NSMutableArray arrayWithObject:@"Foo"];
        [array addObject:@"bar"];
    }
}

Perfect! This all seems to work fine — and it even works fine (as would be expected) for non-autoreleased instances created using [[... alloc] init]. Everything works fine until I start involving any UIKit classes.

For example, let’s create a UIButton and see what happens:

while (true) {
    @autoreleasepool {
        UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        button.frame = CGRectZero;
    }
}

Now, the memory usage increases ad infinitum — effectively, it appears that the @autoreleasepool is having no effect.

So the question is why does @autoreleasepool work fine for the NSMutableArray and keep the memory in-check, but when applied to a UIButton the heap continues to grow?

Most importantly, how can I keep the heap from expanding endlessly when using UIKit classes in an endless loop like this, and what does this tell us about the best practices for ARC in while(true) or while(keepRunningForALongTime) style loops?

My gut feeling on this is (and I could be totally wrong) is that it’s perhaps something about how the while (true) keeps the runloop from cycling, which is keeping the UIKit instances in memory rather than releasing them… But clearly I’m missing something in my understanding of ARC!

(And to eliminate an obvious cause, NSZombiedEnabled is not enabled.)

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-06-18T05:57:28+00:00Added an answer on June 18, 2026 at 5:57 am

    Right, I have done some more thinking about this, together with the great contributions from bbum and Wade Tegaskis regarding blocking the runloop, and realised that the way to mitigate this sort of issue is by letting the runloop cycle, by using the performSelector:withObject:afterDelay: which lets the runloop continue, whilst scheduling the loop to continue itself in the future.

    For example, to return to my original example with the UIButton, this should now be rewritten as a method like this:-

    - (void)spawnButton {
        UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        button.frame = CGRectZero;
        [self performSelector:@selector(spawnButton) withObject:nil afterDelay:0];
    }
    

    This way, the method ends immediately and button is correctly released when it goes out of scope, but in the final line, spawnButton instructs the runloop to run spawnButton again in 0 seconds (i.e. as soon as possible), which in turn instructs the runloop to run… etc etc, you get the idea.

    All you then need to do is call [self spawnButton] somewhere else in the code to get the cycle going.

    This can also be solved similarly using GCD, with the following code which essentially does the same thing:

    - (void)spawnButton {
        UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
        button.frame = CGRectZero;
        dispatch_async(dispatch_get_main_queue(), ^{
            [self spawnButton];
        });
    }
    

    The only difference here is that the method call is dispatched (asynchronously) onto the main queue (main runloop) using GCD.

    Profiling it in Instruments I can now see that although the overall allocation memory is going up, the live memory remains low and static, showing that the runloop is cycling and the old UIButtons are being deallocated.

    By thinking about runloops like this, and using performSelector:withObject:afterDelay: or GCD, there are actually a number of other instances (not just with UIKit) where this sort of approach can prevent unintentional “memory leaks” caused by runloop lockups (I use that in quotations because in this case I was being a UIKit rogue.. but there are other cases where this technique is useful.)

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

link Im having trouble converting the html entites into html characters, (&# 8217;) i
I've got a string that has curly quotes in it. I'd like to replace
I'm interested in microtypography issues on the web. I want a tool to fix:
In my XML file chapters tag has more chapter tag.i need to display chapters
I'm parsing an RSS feed that has an ’ in it. SimpleXML turns this
I don't have much knowledge about the IPv6 protocol, so sorry if the question
I'm trying to convert HTML to plain text. I get many &\#8217; &\#8220; etc.
i got an object with contents of html markup in it, for example: string
I am using Paperclip to handle profile photo uploads in my app. They upload
Let's say I'm outputting a post title and in our database, it's Hello Y’all

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.