Filling an NSMutableArray

Discussion in 'iOS Programming' started by Olbert000, Feb 7, 2011.

  1. Olbert000, Feb 7, 2011
    Last edited by a moderator: Feb 8, 2011

    Olbert000 macrumors newbie

    Joined:
    Feb 7, 2011
    #1
    I am having problems filling my an NSMutableArray one object at a time. Here is some sample code to illustrate my problem:

    Code:
    NSMutableArray* myArray = [[NSMutableArray alloc] init];
    NSMutableString* myString = [[NSMutableString alloc] initWithString:@"a"];
    for (int i=0;i<5;++i){
        [myArray addObject:myString];
        [myString appendString:@"a"];
    }
    for (int i=0;i<5;++i){
        NSLog(@"%@",[myArray objectAtIndex:i]);
    }
    
    Now this produces an output of:
    aaaaa
    aaaaa
    aaaaa
    aaaaa
    aaaaa

    Which is quite different to the output I expected:
    a
    aa
    aaa
    aaaa
    aaaaa

    I am a beginner to Objective C and am unsure why this is.
     
  2. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #2
    You are adding the same string every time. So each element of the array is pointing to the exact same string. You need to create a new string and add it each iteration of the the loop.
     
  3. andrew086 macrumors regular

    Joined:
    Dec 31, 2009
    #3
    try this:
    Code:
    	NSMutableArray* myArray = [[NSMutableArray alloc] init];
    	NSMutableString* myString = [[NSMutableString alloc] initWithString:@"a"];
    	for (int i=0;i<5;++i){
    		[myArray addObject:[myString copy]];
    		[myString appendString:@"a"];
    	}
    	for (int i=0;i<5;++i){
    		NSLog(@"%@",[myArray objectAtIndex:i]);
    	}
    	[myArray release];
    	[myString release];
    what's happening is what robbieduncan said. it adds the myString string 5 times, but it all 5 of them are pointing to the same location in memory.
     
  4. Comrade Yeti macrumors newbie

    Joined:
    Nov 3, 2010
    #4
    Code:
    [myArray addObject:[myString copy]];
    violates the memory guidelines... throw an autorelease on the end to avoid memory leaks

    Code:
    [myArray addObject:[[myString copy] autorelease]
    See Apple's memory guidelines for a refresher:
    "You only release or autorelease objects you own.
    You take ownership of an object if you create it using a method whose name begins with “alloc” or “new” or contains “copy” (for example, alloc, newObject, or mutableCopy), or if you send it a retain message.
    You use release or autorelease to relinquish ownership of an object."
    http://developer.apple.com/library/ios/#documentation/cocoa/Conceptual/MemoryMgmt/Articles/mmRules.html#//apple_ref/doc/uid/20000994-BAJHFBGH
     

Share This Page