Dmitry Labetsky
Dmitry Labetsky

Reputation: 31

NSString stringWithFormat called XX times causes memory warning

I started to monitor app memory usage using technique described in here: Programmatically retrieve memory usage on iPhone

I wrote 3 tests to try it out and this is what I found:

- (void)test1 {
for (int i = 0; i < 1000; i++) {
    NSMutableString *str = [NSMutableString stringWithString:@""];
    for (int j = 0; j < 1000; j++) {
        [str appendString:@"some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string "];
    }
}    

- (void)test2 {
for (int i = 0; i < 100000; i++) {
    @autoreleasepool {
        NSString *stri = @"";
        stri = [NSString stringWithFormat:@"%d some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really", i];
    }
}


- (void)test3 {
NSString *str = @"";
for (int i = 0; i < 500; i++) {
    str = [str stringByAppendingFormat:@"%d some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really", i];
}

When I call test1 or test3 memory gets allocated and deallocated properly - I can see it using the report_memory function described in the link above. But when I call test2 memory does not get deallocated - report_memory goes up and up. If I call test2 several times my app receives memory warning and gets terminated.

I'm using ARC. Can anyone explain what's going in here?

Upvotes: 2

Views: 550

Answers (3)

Dmitry Labetsky
Dmitry Labetsky

Reputation: 31

Nailed it!!! I enabled Zombie Objects and forgot about them thus any allocated objects were not getting deallocated even when I was using the @autoreleasepool block.

Upvotes: 1

Kyokook Hwang
Kyokook Hwang

Reputation: 2762

stringWithFormat returns a NSString object who is autoreleased. Thus, the object will be released when autorelease pool is released at the end of this thread.

Upvotes: 1

Mathew Varghese
Mathew Varghese

Reputation: 4527

This is because you are using separate auto released instances on each iteration. The first case you have a single object called str and you are appending to the same instance. That is why the memory is not leaking there.

Try change the call like this and check,

- (void)test2 
{
    NSString *str = @"";
    for (int i = 0; i < 100000; i++) 
    {
       str = [str stringByAppendingFormat:@"%d some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really long string some really", i];
    }
}

Upvotes: 0

Related Questions