Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Boopyman

macrumors newbie
Original poster
Oct 6, 2009
14
0
I'm having an issue where my app crashes due to a memory problem. I have an NSThread, a while loop within this one, and within the while loop, an if statement. I have two autorelease pools, but since I don't understand the concept of memory management too well, I don't know how to stop the leaking. My loop runs about 100 times maximum.

Here's my code:

Code:
-(void)startTheBackgroundJob {

	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
	
	[NSThread sleepForTimeInterval:6];  
	
	
	int i = 0;
	BOOL done = NO;
	
	while (!done) {
		
		NSAutoreleasePool *pool2 = [[NSAutoreleasePool alloc] init];
	
		if (clicked == YES) {
			
	[pool release];
	pool = [[NSAutoreleasePool alloc] init];
				
	i++;
				
	UIImage *screenshot = [UIImage imageWithCGImage:UIGetScreenImage()];
	
	NSData *imageData = UIImagePNGRepresentation(screenshot);
	
	NSString *fileName  = [NSString stringWithFormat:@"image%d.png",i];
				
	NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

	NSString *documentsDirectory = [paths objectAtIndex:0];
	
	documentsDirectory = [documentsDirectory stringByAppendingPathComponent:fileName];
	
	[imageData writeToFile:documentsDirectory atomically:YES];
			[pool2 release];
			}
	else {
		done = YES;
	}
		
	}
	
	
	[pool release];
	
	
	}

Thank you very much in advance!
 
From a quick glance it looks fine, although hard to follow because the indentation is off. You should indent your code properly, really helps with trying to follow the flow. Xcode has a preference for doing this automatically.

Isn't UIGetScreenImage() a private function? And I would assume calling that from a background thread isn't safe, just like the majority of UIKit methods/functions.

IMO, I would remove the two autorelease pools, and only keep one around which you could create/destroy every X iterations, or each iteration, of the loop. Autorelease pools are cheap.
 
Ok well thanks for the suggestions. I have enabled the automatic indenting within XCode, and now only have one autorelease pool. It's not making any difference. Do is it matter if I release the pool and recreate in the while loop or in the if statement?

Here's my code as of now:

Code:
-(void)startTheBackgroundJob {

	NSAutoreleasePool *pool = [[NSAutoreleasePool alloc]init];
	
	[NSThread sleepForTimeInterval:6];  
	
	
	int i = 0;
	BOOL done = NO;
	
	while (!done) {
	
	[pool release];
	pool = [[NSAutoreleasePool alloc] init];
	
	if (clicked == YES) {
			
	[pool release];
	pool = [[NSAutoreleasePool alloc] init];
				
	i++;
				
	UIImage *screenshot = [UIImage imageWithCGImage:UIGetScreenImage()];
	
	NSData *imageData = UIImagePNGRepresentation(screenshot);
	
	NSString *fileName  = [NSString stringWithFormat:@"image%d.png",i];
				
	NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);

	NSString *documentsDirectory = [paths objectAtIndex:0];
	
	documentsDirectory = [documentsDirectory stringByAppendingPathComponent:fileName];
	
	[imageData writeToFile:documentsDirectory atomically:YES];
			
	}
		
		
	else {
		
	done = YES;
		
	}
		
	}
		
	[pool release];
	
	
	}

Now I think there's a pretty big possibility that you're right about not being able to run this in a secondary thread. The problem is, if I run it in my main thread, the GUI doesn't respond, and I need to press a button to stop taking snapshots. So if you have any ideas about how to do this without another thread, I would be glad to hear it.

Thank you very much for these suggestions.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.