1

I've got a strange problem about [NSString stringWithFormat:@""];
This is my code:

NSString *log;
[NSTimer scheduledTimerWithTimeInterval:0.05 target:self selector:@selector(someFunction) userInfo:nil repeats:YES];

- (void) someFunction
{
    log = [NSString stringWithFormat:@"a very big string here....."];
}

this single line "log = [NSString stringWithFormat];" increases memory very fast.
I can't find any reason why :(
BTW I use ARC.

Rendel
  • 1,794
  • 3
  • 13
  • 16
  • Maybe +[NSString stringWithFormat:] allocates a new string everytime. In addition, you are calling this method 20 times a second. – Brian Tracy Mar 01 '14 at 18:22
  • Why do you have to assign a *“very big string”* every 0.05 seconds new? — If it's a literal, you can even avoid to create a new copy – JDS Mar 01 '14 at 18:23
  • Do you ever assign a different variable to `log`? This could explain that it's kept alive. – zneak Mar 01 '14 at 18:26
  • No, I use log only 1 time: in that function, that's all – Rendel Mar 01 '14 at 18:27
  • Note that in *Instruments*, you don't have to look at allocations, allocations will increase for ever an that is **normal**. You have to look at leaks!!! – Merlevede Mar 01 '14 at 18:28
  • I debugged It already 100 times with instruments to check for memory leaks, but there are no leaks showing :( – Rendel Mar 01 '14 at 18:29
  • @George So what is the problem then??? How do you know the memory isn't being freed? – Merlevede Mar 01 '14 at 18:30
  • @Merlevede I know because when I look at debug session the memory is increasing and increasing.... – Rendel Mar 01 '14 at 18:31
  • I'm sorry, what do you mean by 'look at debug session'? – Merlevede Mar 01 '14 at 18:32
  • show debug navigator window in xcode (cmd+6) – Rendel Mar 01 '14 at 18:34
  • `stringWithFormat` produces an autoreleased object. Until you exit the nearest enclosing autorelease boundary the object will not be released. – Hot Licks Mar 01 '14 at 18:57

2 Answers2

2

I wouldn't worry about your memory not being released, because as you have seen here, we're pretty much agreeing that you're doing the right thing.

My concern is about why the memory is being reported like that. I thought the memory monitor might be reporting allocations (which even released keep accumulating).

My version of XCode on this machine is lower and it doesn't have the memory monitor, so I can't check it out here. But I found this link... maybe you can check what they say about the Zombies option.

Also you can use Instruments as a second tool to see what's happening.

Community
  • 1
  • 1
Merlevede
  • 8,140
  • 1
  • 24
  • 39
  • Oh yeeess baby :D :D Zombies option was the great answer. I wasted like 4-5 hours to correct this. Thanks man – Rendel Mar 01 '14 at 18:54
0

It's increasing memory because the stringWithFormat: method makes a copy of the format string. Since the log variable appears to be an instance variable, ARC will not do a release on log until the containing class is released or the class sets log to nil.

If you want the memory allocated to 'log' to be freed quickly, then set log = nil; before you exit someFunction.

Jack Cox
  • 3,290
  • 24
  • 25
  • I tried that too, I wrote: log = nil; log = [NSString stringWIthFormat:.....]; but memory is still increasing – Rendel Mar 01 '14 at 18:37
  • Another approach would be to break up the long string into smaller chunks, assigning them to log, processing log, then reusing log. – Jack Cox Mar 01 '14 at 18:39
  • hmm... No, I want to have log variable with updated content. If I write in that order log variable will be nil always :( – Rendel Mar 01 '14 at 18:39
  • hmm.. how strange, event in that order memory is increasing :( – Rendel Mar 01 '14 at 18:44
  • is 'log' only used within someFunction? – Jack Cox Mar 01 '14 at 18:45
  • now yes, but in future I want to use it outside of someFunction – Rendel Mar 01 '14 at 18:46
  • @JackCox setting the object to nil, and then assigning it to another variable has the same effect as ONLY doing the second assignment. – Merlevede Mar 01 '14 at 18:49
  • I would make 'log' local variable to someFunction. When you need it outside of someFunction later then just return it to the caller and ARC will take care of releasing it when the caller is done with it. Until then ARC will release the memory when someFunction returns. – Jack Cox Mar 01 '14 at 18:49
  • Thank you all guys. Merlevede's answer helped me. – Rendel Mar 01 '14 at 18:55