I'm having difficulty modifying a mutable array. I'd say that I am an an Intermediate level ios programmer - I'm not a complete newb, but I often forget some of the basics.
The error I'm getting is:
-[__NSCFArray insertObject:atIndex:]: mutating method sent to immutable object'
Trouble is, I declared and initialized it as an NSMutableArray. I have gone at this from a ton of different angles - I was hoping someone might give me some ideas. Here are the important highlights:
The viewcontroller looks like this:
@interface HomeScreen : UIViewController
{
...
NSMutableArray *arrayOfNewsItems;
}
...
- (void)GoAheadAndGetData;
- (void)getTweets;
- (void)renameKeysIn:(NSMutableArray*)source :(NSMutableArray*) final;
...
(some properties...)
@endAfter the first viewController loads, the user clicks a button. The button is connected to a modal segue on the storyboard, so the following method runs:
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender
{
if ([sender tag] == 1) { // if the button for loading the table is pushed:
// If there is a valid connection, go ahead and try to connect
if ([self connected]) {
[self GoAheadAndGetData];
} else { ...
...
(This all works fine, by the way)
So from there, the GoAheadAndGetData (which is where the array is initialized, and all data is obtained) method looks roughly like this:
- (void)GoAheadAndGetData
{
// This function starts by getting data automatically from my yahoo pipe,
// transfering it into a mutable array, then checks for other feeds
// create the string for making the api call to the yahoo pipes site
NSString* theURL = [NSString stringWithFormat:@"
http://... etc..."];
// declare and assign variables necessary to generate the actual request
NSError* err = nil;
NSURLResponse* response = nil;
NSMutableURLRequest* request = [[NSMutableURLRequest alloc] init];
NSURL* URL = [NSURL URLWithString:theURL];
[request setURL:URL];
[request setCachePolicy:NSURLRequestReloadIgnoringLocalCacheData];
[request setTimeoutInterval:30];
// make the actual url request - get the data from yahoo pipes, in json
NSData* jsonData = [NSURLConnection sendSynchronousRequest:request returningResponse:&response error:&err];
// assign the entire result to a large dictionary object
NSDictionary *entireResults = [NSJSONSerialization JSONObjectWithData:jsonData options:kNilOptions error:&err];
// grab the "value" field
NSDictionary *valueFieldOnly = [entireResults objectForKey:@"value"];
// ****** This is where the array in question is initialized as mutable ********
// grab the "items" field
arrayOfNewsItems = [[NSMutableArray alloc] init];
arrayOfNewsItems = [valueFieldOnly objectForKey:@"items"];
//***************************************************************
// Now check for Twitter feed settings, and merge them into the rest
NSString *settingsKey = [[NSString alloc] initWithString:@"keyTwitterState"];
BOOL toggleValue = [[NSUserDefaults standardUserDefaults] boolForKey:settingsKey];
if (toggleValue) {
NSLog(@"Called getTweets, because twitter state answered as true.");
[self getTweets];
} else {
NSLog(@"twitter state answered as false.");
}
} // end method GoAheadAndGetData
// ******* This all works, so far, also.
The following method is where the error is generated. But I find it baffling - all I'm doing is calling a mutable method on a mutable array. I won't include all of the code here, because it's long, and I'm pretty sure nothing affects anything... most of it is directly from Twitter's api documentation anyway.
- (void)getTweets
{
...
if (!responseData) {
// inspect the contents of error
NSLog(@"Error 1: %@", error);
} else {
NSError *jsonError;
NSMutableArray *timeline = [NSJSONSerialization JSONObjectWithData:responseData options:NSJSONReadingMutableLeaves error:&jsonError];
if (timeline) { // at this point, we have an object that we can parse
// Having retrieved the user's home Twitter timeline, we can now merge it with the newsItems.
// The keys in the timeline need to match the arrayofnewsItems, in order for them to be sorted, so call renameKeys
timeline = [self renameKeysIn:timeline];// this works fine
NSLog(@"\nReturned value from rename Keys. \n%@^^Item 1:^^\nTimeline count: %d \narrayOfNewsItems count: %d",[timeline objectAtIndex:0], [timeline count],[arrayOfNewsItems count]);
// Then we can merge them:
// ****************** THIS IS THE MAIN ERROR POINT **********
[arrayOfNewsItems addObjectsFromArray:timeline];
// ******* THIS LINE RETUNS THE Mutable method/non-mutable object error.
NSLog(@"Added the tweet array to the newsitems array. Count: %d",[arrayOfNewsItems count]);
// Then finally, sort:
NSSortDescriptor *sortByDateDescriptor = [[NSSortDescriptor alloc] initWithKey:@"pubDate" ascending:YES];
NSArray *sortDescriptors = [NSArray arrayWithObject:sortByDateDescriptor];
NSLog(@"\ncreated sort descriptors. Getting ready to sort the array.");
NSMutableArray *sortedArray = [NSMutableArray arrayWithArray:[arrayOfNewsItems sortedArrayUsingDescriptors:sortDescriptors]];
[arrayOfNewsItems addObjectsFromArray:sortedArray];
} else {
// inspect the contents of jsonError NSLog(@"--------------- Error: ---------------- \n\n%@", jsonError);
}
}
}];
} // if ([twitterAccounts count] > 0)
} // if (granted)
}];
} // end getTweets
And that's basically it. Sorry about the formatting. At this point, I don't feel comfortable hosting the entire project
Replies
The fact that I see these two lines right together in your code, in fact, means you still do not understand some of the fundamentals.
Sure, you started off right by alloc'ing an NSMutableArray. But then you go and overwrite that with whatever is in valueFieldOnly for the key "items". I don't see anywhere in the code you posted where you have set that value. So it's safe to assume from the error messages you have, that this is only an NSArray. If you are trying to initialize an NSMutableArray to contain the contents of "items", then you could use the the arrayWithArray method to init an NSMutableArray with the contains of "item", or the mutableCopy method to make a mutable copy of "items".
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like AwesomeYour first line is redundant since you are replacing the value in the second line. I suspect the object you are getting back from objectForKey: is a regular NSArray, not mutable.
And you should look into using properties btw.
New app - See screenshots and details at www.globaclock.com.
If you want to
- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like Awesome- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like Awesome- Spam
- Abuse
- Troll
0 • Off Topic Insightful Disagree Dislike Like Awesome