Cannot release a mutableCopy despite having just created it

Discussion in 'iOS Programming' started by peptidyl, Dec 10, 2009.

  1. peptidyl
    Expand Collapse
    macrumors newbie

    Dec 10, 2009
    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:

    + (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\\"];
    	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. dejo
    Expand Collapse


    Staff Member

    Sep 2, 2004
    The Centennial State
    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. kainjow
    Expand Collapse
    Moderator emeritus


    Jun 15, 2000
    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:
    NSLog(@"%@",[[NSNumber numberWithInt:[aComponentsList retainCount]] stringValue]);
    Just do this:
    NSLog(@"%d",[aComponentsList retainCount]);
  4. jnic
    Expand Collapse
    macrumors 6502a

    Oct 24, 2008

  5. PhoneyDeveloper
    Expand Collapse
    macrumors 68030


    Sep 2, 2008
    What does this mean?

Share This Page