views:

340

answers:

3

I detach a thread to my method wich has a while-loop and even if I have an autoreleasePool, I release the objects manually since the while-loop can continue for a while... The problem is that after a while, the app crashes due to memory problems and if I look in Instruments I can see a huge pile of NSString allocated and a stairway to heaven is created in the graph... What do I miss to release?

while (keepGettingScores)  
{  
    NSString *jsonString = [[NSString alloc] initWithContentsOfURL:url encoding:NSUTF8StringEncoding error:nil];  
    NSDictionary *json = [jsonString JSONValue];  
    [jsonString release];   

    NSMutableArray *scores = [[NSMutableArray alloc] init];  
    [scores setArray:(NSMutableArray*)[[jsonString JSONValue] objectForKey:@"scores"]];

    NSSortDescriptor *sorter = [[NSSortDescriptor alloc] initWithKey:@"totalScore" ascending:NO];  
    [scores sortUsingDescriptors:[NSArray arrayWithObject:sorter]];  
    [sorter release];  

    [self performSelectorOnMainThread:@selector(updatePlayerTable:) withObject:scores waitUntilDone:NO];  
    [scores release];  

    [NSThread sleepForTimeInterval:1.0];  
}  
A: 

I don't see anything glaring, could there be an issue under the hood in your JSON library?

Greg Martin
I', not using a json library, I did use som 3rd party api but there was a memory leakage in that one (...as in my code...) so I used [NSString jsonVALUE]
niel41
Unless I'm totally missing something, jsonVALUE is not part of Apple's APIs, where is that coming from?
Greg Martin
A: 

Are you draining your pool after your thread is finished executing?

You need to create an NSAutoreleasePool and call its drain method when your thread is finished executing.

In one of my projects, I had a thread that needed to create a lot of autorelease objects and found it useful to periodically drain the pool as the thread was running.

- (void)doStuff:(NSObject *)parent {
    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];      

    /* Do lots of stuff *.
    /* Periodically, I'd drain and recreate the pool */
    [pool drain];
    pool = [[NSAutoreleasePool alloc] init];
    /* The rest of my stuff */

    [pool drain];
}

And doStuff: is called using detachNewThreadSelector:

Dana
Ok, I'll give it a try by draining the pool inside the while loop but then it will happen every one second but maybe that is ok?
niel41
A: 

ok some BIG problems i see is

1

this..

[self performSelectorOnMainThread:@selector(updatePlayerTable:) withObject:scores waitUntilDone:NO]; is passing scores which could be getting retained by something else and that would also retain all the objects it contains.

2

scores is a nsmutablearray and is explicitly defined as NOT THREAD SAFE yet you are passing it across threads.

3

those [blah JSONvalue] things should be autoreleased and that is not apple api, apple has no public JSON api for iphone. that is most likely SBJSON library which puts categories on apple classes(nsstring, nsarray, nsdictionary, etc) for convenient JSON parsing.

drunknbass