Cannot release a mutableCopy despite having just created it

Discussion in 'iPhone/iPad Programming' started by peptidyl, Dec 10, 2009.

  1. macrumors newbie

    Joined:
    Dec 10, 2009
    #1
    Hello all - firstly, a thanks to all of you in advance for your help.

    I tried googling this problem to no avail. The problem is, I create a mutableCopy of an NSArray and assign it to a NSMutableArray, and quickly assign it to something else and then try to release it. The debugger tells me that it stalls on the release, even though I've checked that retainCount = 1. Here's the code for the entire method:

    Code:
    + (void)setUpChapters {
    	
    	NSMutableArray *chapters = [NSMutableArray array];
    	NSMutableArray *componentsFullList = [NSMutableArray array];
    	
    	[componentsFullList addObject:@"Introduction\\A few brief words\\intro.html\\introduction.a.few.brief.words"];
    	[componentsFullList addObject:@"Cells\\A quick look at bacteria\\cells.1.html\\bacteria.LUCA.eukaryote.ribosome"];
    	[componentsFullList addObject:@"\\Testpage\\cells.1.html\\test.delete.me"];
    
    	Chapter *chapter = nil;
    	
    	if (chapter == nil) {
    		for (NSString *aComponent in componentsFullList) {
    			NSArray *aComponentsList = [[aComponent componentsSeparatedByString:@"\\"] copy];
    			NSLog(@"%@",[[NSNumber numberWithInt:[aComponentsList retainCount]] stringValue]); // returns 1
    			NSArray *componentsList = aComponentsList;
    			[aComponentsList release]; // here it stalls
    			chapter = [[Chapter alloc] initWithName:[componentsList objectAtIndex:0]];
    			[chapters addObject:chapter];
    			[chapter release];
    			if ([componentsList objectAtIndex:1]!=NULL) {
    				Section *section = [[Section alloc] initWithName:[componentsList objectAtIndex:1]];
    				[chapter addSection:section];
    				[section release];
    			}
    			TextBody *textBody = [[TextBody alloc] initWithHTMLString:[componentsList objectAtIndex:2]];
    			[chapter addTextBody:textBody];
    			[textBody release];
    			
    			// opening the relevant file to parse into keywords
    			NSString *bundlePath = [[NSBundle mainBundle] bundlePath];
    			NSURL *bundleBaseURL = [NSURL fileURLWithPath: bundlePath];
    			NSURL *bundleBaseURLWithFile = [NSURL URLWithString: [componentsList objectAtIndex:2] relativeToURL: bundleBaseURL];
    
    			NSError *error = nil;
    			NSString *totalDataString = [[NSString alloc] initWithContentsOfURL:bundleBaseURLWithFile encoding:NSUTF8StringEncoding error:&error];
    			NSLog (@"%@", [error localizedDescription]);
    			
    			NSCharacterSet *splitterCharacters = [NSCharacterSet characterSetWithCharactersInString:@" .,!?@£$%^&*()_+-=[]{}'\"/~±<>"];
    			NSMutableArray *keywordList = [[totalDataString componentsSeparatedByCharactersInSet:splitterCharacters] mutableCopy];
    			for (NSString *individual in keywordList) {
    				Keywords *keyword = [[Keywords alloc] initWithString:individual];
    				[chapter addKeywords:keyword];
    				[keyword release];
    			}
    			[keywordList autorelease];
    
    		}
    	}
    	
    	for (Chapter *aChapter in chapters) {
    		chapter = aChapter;
    	}
    	
    	knownChapters = chapters;
    	
    	
    }
    
    Thank you in advance.
     
  2. Moderator

    dejo

    Staff Member

    Joined:
    Sep 2, 2004
    Location:
    The Centennial State
    #2
    Except nowhere in the code you supplied do you actually do that. keywordList is assigned via mutableCopy but then you use it as the basis of a for-each loop and then autorelease it.
     
  3. Moderator emeritus

    kainjow

    Joined:
    Jun 15, 2000
    #3
    Code:
    NSArray *aComponentsList = [[aComponent componentsSeparatedByString:@"\\"] copy];
    NSArray *componentsList = aComponentsList;
    [aComponentsList release]; // here it stalls
    chapter = [[Chapter alloc] initWithName:[componentsList objectAtIndex:0]];
    Briefly looking at the code, I don't see why that would be a problem. componentsSeparatedByString returns an autoreleased object, and then you copy it. copy then will retain it, and then you release it, so we're back to the autoreleased object which doesn't get released until the next run loop iteration (after all your code is done executing).

    BTW the NSNumber in this line is unnecessary:
    Code:
    NSLog(@"%@",[[NSNumber numberWithInt:[aComponentsList retainCount]] stringValue]);
    Just do this:
    Code:
    NSLog(@"%d",[aComponentsList retainCount]);
     
  4. macrumors 6502a

    Joined:
    Oct 24, 2008
    Location:
    Cambridge
    #4
    http://developer.apple.com/iphone/l...ml#//apple_ref/occ/intfm/NSObject/retainCount

     
  5. macrumors 68030

    PhoneyDeveloper

    Joined:
    Sep 2, 2008
    #5
    What does this mean?
     

Share This Page