App using too much memory?

Discussion in 'Mac Programming' started by Aranince, Nov 6, 2009.

  1. macrumors 65816

    Joined:
    Apr 18, 2007
    Location:
    California
    #1
    I'm trying to write a text editor, and I'm working on getting the source list to work(similar to Coda and TextMate). When I open a reletivly small directory, my app works fine. However, when I open a bigger directory, the app crashes saying that it has run out of memory and is unsafe to call malloc.

    Basically what the App is doing right now is populating an NSOutlineView with the files and directories of a directory that the user chooses.

    Code:
    - (void)populateSourceListView {
    	NSFileManager *fileManager = [NSFileManager defaultManager];
    	
    	BOOL isDir, valid;
    	
    	valid = [fileManager fileExistsAtPath:path isDirectory:&isDir];
    	
    	if(valid && isDir) {
    		
    		SourceListItem *rootItem = [[SourceListItem alloc] init];
    		[rootItem setTitle:[path lastPathComponent]];
    		
    		NSArray *files = [fileManager contentsOfDirectoryAtPath:path error:nil];
    		
    		for(int i = 0; i < [files count]; i++) {
    			
    			NSString *file = [files objectAtIndex:i];
    			// If we are a directory
    			NSMutableString *newPath = [[NSMutableString alloc] init];
    			[newPath stringByAppendingFormat:@"%@/%@",path,file];
    			
    			if ([fileManager fileExistsAtPath:newPath isDirectory:&isDir] && isDir == YES) {
    				SourceListItem *newNode = [[SourceListItem alloc] init];
    				[self populateItem:newNode atPath:newPath];
    				[newNode setTitle:file];
    				[rootItem addChild:newNode];
    				[newNode release];
    			} else {
    				SourceListItem *newNode = [[SourceListItem alloc] initLeaf];
    				[newNode setTitle:file];
    				[rootItem addChild:newNode];
    				[newNode release];
    			}
    			
    			[newPath release];
    			
    		}
    		
    		[sourceListContents addObject:rootItem];
    		[rootItem release];
    		[files release];
    	}
    	
    }
    
    - (void)populateItem:(SourceListItem*)item atPath:(NSString*)p {
    	if ([item leaf] == YES) {
    		return;
    	}
    		 
    	NSFileManager *fileManager = [NSFileManager defaultManager];
    		 
    	NSArray *items = [fileManager contentsOfDirectoryAtPath:p error:nil];
    		 
    	for (int i = 0; i < [items count]; i++) {
    		BOOL isDir;
    		NSString *file = [items objectAtIndex:i];
    		NSMutableString *newPath = [[NSMutableString alloc] init];
    		[newPath stringByAppendingFormat:@"%@/%@",p,file];
    		// If we are a directory
    		
    		if ([fileManager fileExistsAtPath:newPath isDirectory:&isDir] && isDir == YES) {
    			SourceListItem *newNode = [[SourceListItem alloc] init];
    			[self populateItem:newNode atPath:newPath];
    			[newNode setTitle:file];
    			[item addChild:newNode];
    			[newNode release];
    		} else {
    			SourceListItem *newNode = [[SourceListItem alloc] initLeaf];
    			[newNode setTitle:file];
    			[item addChild:newNode];
    			[newNode release];
    		}
    		
    		[newPath release];
    		
    	}
    	
    	[items release];
    }
     
  2. macrumors 603

    MorphingDragon

    Joined:
    Mar 27, 2009
    Location:
    The World Inbetween
    #2
    Get Xcode and use instruments, or when running the program. Open a terminal and run "top" without the quotes. This might help show if its using too much ram or its a bug in the code.
     
  3. macrumors 68030

    Catfish_Man

    Joined:
    Sep 13, 2001
    Location:
    Portland, OR
    #3
    If you're not actually leaking memory, then another thing to consider is an autorelease pool inside the loop so you don't build up autoreleased objects.
     
  4. macrumors 603

    Joined:
    Aug 9, 2009
    #4
    Post the source for SourceListItem.


    Code:
    NSMutableString *newPath = [[NSMutableString alloc] init];
    [newPath stringByAppendingFormat:@"%@/%@",p,file];
    
    This code is wrong (in both places).

    Use the NSMutableString method, appendFormat: . It will mutate the existing object.

    Or use the NSString method +format: instead. It will return an autoreleased string, so deal with it accordingly.


    Code:
       [files release];
    }
    
    ...
       [items release];
    }
    
    This code is wrong (in two places, with different variable names).

    You don't own the NSArray object at that point.


    Your factoring is horrible. Don't copy and paste code that's exactly the same. There should be only one place that performs the recursive descent, not two. You're making it twice as hard to debug.
     
  5. thread starter macrumors 65816

    Joined:
    Apr 18, 2007
    Location:
    California
    #5
    Yea I was too cought up In trying to understand and get the dang thing to work. I'll try your suggestions....thanks
     

Share This Page