Evgeniy Kleban
Evgeniy Kleban

Reputation: 6940

Managing arrays - mutating method sent to immutable object

I try to populate existing array with other array:

if (!self.photos){
    self.photos = [responseDictionary valueForKeyPath:@"data"];
} else {
    NSArray *newPhotosFromFeed = [responseDictionary valueForKeyPath:@"data"];
    [self.photos addObjectsFromArray:newPhotosFromFeed];
}

Compiler throw me an error - mutating method sent to immutable object .

Photos declared like this:

@property (nonatomic) NSMutableArray *photos;

Method declaration (from Apple.developer) is following:

- (void)addObjectsFromArray:(NSArray *)otherArray

So, how am i violate the rules?

I add NON-mutable array NSArray *newPhotosFromFeed to MUTABLE array self.photos.

So why am i get that error??

Upvotes: 1

Views: 70

Answers (2)

Wain
Wain

Reputation: 119031

If this line is called first:

self.photos = [responseDictionary valueForKeyPath:@"data"];

then you will be storing an immutable array in a mutable property. The compiler can't tell it's wrong and the runtime doesn't check so you don't know it's happening. Then, later, when you call:

[self.photos addObjectsFromArray:newPhotosFromFeed];

you get the crash.

So, you should always ensure that the object being set to photos is mutable, the easiest way it by taking the mutableCopy as that will work on both mutable and immutable source objects:

self.photos = [[responseDictionary valueForKeyPath:@"data"] mutableCopy];

Upvotes: 2

Sam Fischer
Sam Fischer

Reputation: 1472

Here's the fix :

self.photos = [responseDictionary valueForKeyPath:@"data"].mutableCopy;

and

NSArray *newPhotosFromFeed = [responseDictionary valueForKeyPath:@"data"].mutableCopy;

You're attempting to set an NSMutableArray to a NSArray. That doesn't work without using mutableCopy. Use mutableCopy to create a mutable copy of the NSArray and that object becomes an NSMutableArray.

Upvotes: 1

Related Questions