Reputation: 3524
I have an NSMutableArray
called myMutbaleArray
that looks like this when I log it
2015-12-08 17:04:21.679 APP[3342:573379] (
{
id = 19;
"num_test" = 100000;
url = "http://fsad.com";
},
{
id = 20;
"num_test" = 100001;
url = "http://teeeet.com";
}
)
And I want to add an object that looks like this
{
id = 21;
"num" = 100002;
url = "http://example.com";
}
So I am trying this
[myMutbaleArray addObject:@{ @"id":@"23",@"num_test":@"100000", @"url":mainDict[@"website_url"],@"website_name":@"website"}];
But when I do this I get
Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFArray insertObject:atIndex:]: mutating method sent to immutable object'
I initialize the array like this
@interface {
NSMutableArray *socailArray;
}
//inside connectionDidFinishLoading
socailArray = [dataDict valueForKey:@"socail"];
Why can I add another dictionary to the MutableArray?
Thanks
Upvotes: 0
Views: 657
Reputation: 790
With socailArray = [dataDict valueForKey:@"socail"];
, the type of [dataDict valueForKey:@"socail"]
is NSArray
, so it auto cast socailArray
into NSArray
, that's why you can not insert thing into this.
To avoid this, you must be hold socailArray
as NSMutableArray
using:
socailArray = [[dataDict valueForKey:@"socail"] mutableCopy];
Hope this could help.
Upvotes: 0
Reputation: 7570
If you see this, your array is actually not a mutable array. Here is the hint:
-[__NSCFArray insertObject:atIndex:]
^^^^^^^^^^^
The object is of type __NSCFArray
, which is an internal counterpart of NSArray
.
Even if you declare your variable as NSMutableArray
the pointer can point to an object of any type (event for example NSRegularExpression
). Important is, how it is created.
This happens to most people if they serialise an array either using NSUserDefaults
, NSJSONSerialization
or what ever.
The key is to create a mutable copy when the array gets deserialised using
-[NSArray mutableCopy]
Note that this is not deep-copy. This means an array contained in the root array will not be mutable copied and needs to be replaced separately.
Deep copying can be achieved using this:
// array
NSArray *originalArray = @[@"a", @"b", @[@1, @2]];
NSMutableArray *mutableArray = (NSMutableArray *)CFPropertyListCreateDeepCopy(kCFAllocatorDefault, (CFArrayRef)originalArray, kCFPropertyListMutableContainers);
// dictionary
NSDictionary *originalDictionary = @{@"a": @"b", @"c": @[@{@"abc": @123}]};
NSMutableDictionary *mutableDictionary = (NSMutableDictionary *)CFPropertyListCreateDeepCopy(kCFAllocatorDefault, (CFDictionaryRef)originalDictionary, kCFPropertyListMutableContainers);
Upvotes: 1
Reputation: 4347
You should change init to:
//inside connectionDidFinishLoading
socailArray = [NSMutableArray arrayWithArray:[dataDict valueForKey:@"socail"]];
Because: [dataDict valueForKey:@"socail"]
is a NSArray
.
Upvotes: 0