newProgrammer:please help with insertString!

Discussion in 'Mac Programming' started by Scouze, Aug 17, 2010.

  1. Scouze macrumors newbie

    Joined:
    Mar 3, 2010
    #1
    Hi,

    I'm sure it's something really simple but the following code in my project:

    NSMutableString *temp = [[NSMutableString alloc] initWithString:[firstNumber stringValue]];
    NSArray *splitInput = [[NSArray alloc]initWithArray:[temp componentsSeparatedByString:mad:"x"]];
    NSMutableString *f = ( NSMutableString * )[splitInput objectAtIndex:1];
    [f insertString: ( NSMutableString * ) @"00000000" atIndex:0];

    Where 'firstNumber' is the outlet from a standard text field in the main window.

    It produces the error:

    Attempt to mutate immutable object with insertString:atIndex:

    My code's a very early stage timecode calculator, so the user can enter '4x23' and the '23' needs to ultimately be padded with zeroes. I realise there's probably a better way by using 'NSNumberFormatter', but now I've a flea in my ear and I'd just like to know what I've done wrong.

    Many thanks!

    Todd.
     
  2. robbieduncan Moderator emeritus

    robbieduncan

    Joined:
    Jul 24, 2002
    Location:
    London
    #2
    NSStrings cannot be changed once created. You must use a NSMutableString (creating it if required).

    Edit: just seen you have attempted to use an NSMutableString but you have done it wrong. The split creates an array of NSString objects. You cannot cast them to NSMutableString: you are casting the wrong way. You can cast a subclass (NSMutableString) to a superclass (NSString) but not the other way. You need to create a new mutable object.
     
  3. Scouze thread starter macrumors newbie

    Joined:
    Mar 3, 2010
    #3
    Thanks, Robbie!

    I'll go back to reading about sub classes! I guess, though, that I need to create a temporary, mutable string and insert/replace it's contents with the user input held in the array and then do the 'padding'.

    Todd


     
  4. jamawa macrumors newbie

    Joined:
    Jul 7, 2009
    #4
    Another option would be to use NSString's stringByAppendingString f.e. by replacing the last two lines of your code with:

    NSString *f = [[NSString stringWithString:mad:"00000000"] stringByAppendingString:[splitInput objectAtIndex:1]];

    and work from there.
    Just a thought.
     
  5. Scouze thread starter macrumors newbie

    Joined:
    Mar 3, 2010
    #5
    And a much better thought than mine. Thanks!

     
  6. chown33 macrumors 604

    Joined:
    Aug 9, 2009
    #6
    The unwieldy and redundant [NSString stringWithString:mad:"00000000"] is redundant and unwieldy.

    Replace it with @"00000000" and it works as well.

    That's because @"anything" is an actual NSString object, and it responds to the same messages as any NSString does:
    Code:
    NSString *f = [@"00000000" stringByAppendingString:[splitInput objectAtIndex:1]];
    

    This code is also redundant. First, temp doesn't need to be mutable. None of the operations or expressions it participates in have any need to modify it. In particular, splitting it does not require a mutable string.

    Therefore, this expression yields a suitable string:
    Code:
    NSMutableString *temp =[firstNumber stringValue];
    
    Even without knowing what type firstNumber is.

    And this code is redundant for the same reason:
    Code:
    NSArray *splitInput = [[NSArray alloc]initWithArray:[temp componentsSeparatedByString:@"x"]];
    It's unnecessary to alloc and init an entire new IMMUTABLE NSArray, when the one returned by componentsSeparatedByString meets every need. Furthermore, the alloc'ed array is leaking, because you own it but haven't released it. An array from componentsSeparatedByString is NOT owned, so WON'T leak when NOT released.
     

Share This Page