views:

348

answers:

3

I read that non mutable data types can't be modified once created.(eg NSString or NSArray).

But can they be re-initialized to point to a different set of objects?

If so, do I use release to free any alloc from first time round in between uses? eg:

myArray declared as NSArray *myArray in interface, and as nonatomic/retain property.myArray set in initialization code to a point to an array of strings as follows.

self.myArray = [myString componentsSeparatedByString:@","];

But later I want to re-initialize myArray to point to a different set of strings

self.myArray = [myOtherString componentsSeparatedByString:@","];

Is it possible? Thanks...

A: 

Of course they can. Saying that an NSArray is immutable doesn't mean that an attribute of a class of that type cannot be changed. You can't change the content, but you can assign new content to it.

If you want to make also changing the reference impossible you should use const keyword.

Jack
But this isn't re-initialization of the array. It is creating a new instance and assigning the pointer to point to that new instance. Very different.
bbum
A: 

Yes you can reinitialized the NSArray. Here is the sample code that i used to re-initialized the NSArray.

NSString *keywords = @"FirstName|LastName|Address|PhoneNumber";
NSArray *arr = [keywords componentsSeparatedByString:@"|"];
NSLog(@"First Init - %@,%@,%@,%@",[arr objectAtIndex:0],[arr objectAtIndex:1],
                                  [arr objectAtIndex:2],[arr objectAtIndex:3]);
arr = nil;

keywords = @"First_Name|Last_Name|_Address|_PhoneNumber";
arr = [keywords componentsSeparatedByString:@"|"];
NSLog(@"Second Init - %@,%@,%@,%@",[arr objectAtIndex:0],[arr objectAtIndex:1],
                                   [arr objectAtIndex:2],[arr objectAtIndex:3]);
Jim
Another wrong example! You **must not** release the array, because you did not get it by using `alloc`/`copy*`/`new*`! This will throw a EXC_BAD_ACCESS or something similar at some time in the future, when the array is autoreleased!
Adam Woś
Yes you are right adam. I changed the code.:-)
Jim
That's better :)
Adam Woś
Why not just NSLog the array? Why print each object individually? (Other than that, +1)
Dave DeLong
+2  A: 

It really depends what you mean with re-initialize. You can assign another immutable object to a pointer, because the pointers aren't constant.

Example:

@interface MyObj : NSObject {
    NSString *name;                    // not needed in 64bit runtime AFAIK
}
@property(retain) NSString *name;      // sane people use copy instead of retain
                                       // whenever possible. Using retain can
                                       // lead to some hard to find errors.
@end

/* ... another file ... */

MyObj *theObject = [[[MyObj alloc] init] autorelease];

theObject.name = @"Peter";
NSString *oldName = theObject.name;

NSLog(@"%@", theObject.name);   // -> Peter
NSLog(@"%@", oldName);          // -> Peter

theObject.name = @"Martin";
NSLog(@"%@", theObject.name)    // -> Martin
NSLog(@"%@", oldName)           // -> Peter

If the behavior above is what you want, that's fine.

If you want that last line to return Martin you're in trouble. Those are constant strings and are not meant to be modified. You could, if you really want, modify the memory of the object directly, but this is dangerous and not recommended. Use mutable objects if you need such behaviour.

Georg
Thanks. I'm slowly grasping the distinction between managing pointers and managing the things they point at...
Nigel