15
votes

what is difference mutable and immutable

like

NSString and NSMutableString.

NSArray and NSMutableArray.

NSDictionary and NSMutableDictionary.

What is difference between mutable object and the other object[which i guess immutable]

@thanks in advance.

8
A good followup question would be why NSArray, NSString, NSSet, NSDictionary, etc. are immutable. - Rudy Velthuis

8 Answers

17
votes

A mutable object can be mutated or changed. An immutable object cannot. For example, while you can add or remove objects from an NSMutableArray, you cannot do either with an NSArray.

Mutable objects can have elements changed, added to, or removed, which cannot be achieved with immutable objects. Immutable objects are stuck with whatever input you gave them in their [[object alloc] initWith...] initializer.

The advantages of your mutable objects is obvious, but they should only be used when necessary (which is a lot less often than you think) as they take up more memory than immutable objects.

8
votes

Mutable objects can be modified, immutable objects can't.

Eg: NSMutableArray has addObject: removeObject: methods (and more), but NSArray doesn't.

Modifying strings:

NSString *myString = @"hello";
myString = [myString stringByAppendingString:@" world"];

vs

NSMutableString *myString = @"hello";
[myString appendString:@" world"];

Mutable objects are particularly useful when dealing with arrays,

Eg if you have an NSArray of NSMutableStrings you can do:

[myArray makeObjectsPerformSelector:@selector(appendString:) withObject:@"!!!"];

which will add 3 ! to the end of each string in the array.

But if you have an NSArray of NSStrings (therefore immutable), you can't do this (at least it's a lot harder, and more code, than using NSMutableString)

8
votes

The basic difference is:

  • NSStrings cannot be edited, only reassigned. This means when the value of an NSString changes, it is actually pointing to a new location in memory.

  • NSMutableString objects can be edited and maintain the same pointer.

A common practical difference is:

  • If you create 1 NSString and then assign another one to it, then edit either one of them, they will now be pointing to different strings.

  • If you do the same thing with NSMutableStrings, but then just edit one of them (not reassign it), they will both be pointing to the newly edited object.

5
votes

A mutable object can be mutated or changed. An immutable object cannot. For example, while you can add or remove objects from an NSMutableArray, you cannot do either with an NSArray.

2
votes

The english definition of "mutable" is really all you need here. Mutable objects can be modified after creation. Immutable objects cannot be modified after creation. That applies to all of the classes you listed.

Practically speaking, all of the mutable classes are subclasses of the immutable ones, and each adds its own interface to allow programmatic modification of the object, like addObject:, setObject:forKey:, etc...

2
votes

Everyone says you can't change/modify an immutable object. I have a different way of explaining. You can modify it, but then you would be creating a new pointer to the new object, its not like you modified the old object, its a brand. New. Object. Any pointer that had a previously pointing pointer to it, would not see its change. However if its a Mutable Object, any previously pointing object to it would be seeing its new value. See the examples. FYI %p prints the pointer location in heap.

 NSString * A = @"Bob";
    NSString * B = @"Bob";
    NSString * C = @"Bob1";
    NSString * D = A;
    NSLog(@"\n %p for A \n %p for B \n %p for C \n %p for D",A,B,C,D);

    // memory location of A,B,D are same.

0x104129068 for A
0x104129068 for B
0x104129088 for C
0x104129068 for D


Modifying pointer A's object

A = @"Bob2"; // this would create a new memory location for A, its previous memory location is still retained by B
NSLog(@"\n%p for A \n%p for B \n%p for C \n %p for D",A,B,C, D);

// A has a **new** memory location, B,D have same memory location.

0x1041290c8 for A
0x104129068 for B
0x104129088 for C
0x104129068 for D


// NSMutableString * AA = @"Bob"; <-- you CAN'T do this you will get error: Incompatible pointer types initializing NSMutableString with an Expression of type NSString
    NSMutableString * AA = [NSMutableString stringWithString:@"Bob1"];
    NSString * BB = @"Bob";
    NSString * CC = @"Bob1";
    NSString * DD = AA;
    NSLog(@"\n %p for AA \n %p for BB \n %p for CC \n %p for DD",AA,BB,CC,DD);

    // memory location of AA,DD are same.

0x7ff26af14490 for AA
0x104129068 for BB
0x104129088 for CC
0x7ff26af14490 for DD


Modifying pointer AA's object

  AA = (NSMutableString*)@"Bob3"; // This would NOT create a new memory location for A since its Mutable-- D was and still pointing to some location
    NSLog(@"\n%p for AA \n%p for BB \n%p for CC \n %p for D",AA,BB,CC,DD);

    // memory location of AA,DD are NOT same.

0x104129128 for AA
0x104129068 for BB
0x104129088 for CC
0x7ff26af14490 for DD

As you would imagine, the default storage attribute for all NSString properties is retain. For more information on copy & retain I highly suggest you read this question.NSString property: copy or retain?

1
votes

Mutable can be changed, immutable cannot. When you share a mutable objects, you should expected the some one can change it. When you share an immutable object, you expected the no one will changed.

1
votes

There are some other difference which are interesting a immutable object when copied will instead be retained. There may also be lots of under the hood differences that apple implements for performance reason depend on whether a object is mutable or not, for example, do the substring methods copy the actual bytes of their parent string or do the just point a subrange of the parent string if it is immutable, probable not but who knows.