Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

Scouze

macrumors newbie
Original poster
Mar 3, 2010
7
0
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.
 
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.
 
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


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.
 
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.
 
And a much better thought than mine. Thanks!

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.
 
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.

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]];


Code:
NSMutableString *temp = [[NSMutableString alloc] initWithString:[firstNumber stringValue]];
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.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.