Editting NSMutableDictionary in array - iphone

I've got a question: I've got an NSMutableArray, which I pass on in multiple views. In one of the views, a value of an object inside that array (NSMutableDictionary) can be editted. I do that using the code:
NSMutableDictionary *tester = [[NSMutableDictionary alloc] initWithDictionary:selectedItem copyItems:YES];
NSMutableString *newLoc = [[NSMutableString alloc] initWithString:locationField.text];
[tester setValue:newLoc forKey:#"Location"];
[selectedList replaceObjectAtIndex:[selectedList indexOfObject:selectedItem] withObject:tester];
The problem I'm having with this, is replacing that object in selectedList. It gives the error *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayI replaceObjectAtIndex:withObject:]: unrecognized selector sent to instance 0xa631e30'
It works if I copy the new item in a copy-array of selectedList, and alloc selectedList with the new value again, but the other views are having problem finding that same list again in the array (new allocated location).
TL;DR version: how can I edit a value (through replacing?) inside an NSMutableArray? Why doesn't replaceObjectAtIndex work?
EDIT: It was immutable indeed. Still, the main question remains:
I've got:
NSMutableDictionary *tester = [[NSMutableDictionary alloc] initWithDictionary:geselecteerdItem copyItems:YES];
[geselecteerdItem setValue:nieuweLoc forKey:#"Location"];
[geselecteerdeLijst replaceObjectAtIndex:[geselecteerdeLijst indexOfObject:tester] withObject:geselecteerdItem];
When I'm using: [warningList replaceObjectAtIndex:[warningList indexOfObject:geselecteerdeLijst] withObject:keuzeLijst], it gives me an outofbounds error because the index of the array geselecteerdeLijst obviously changed inside warningList. Any idea's?

selectedList is an immutable array, which doesn't support any modifications. You can do something like this, though:
NSMutableArray *tmp = [NSMutableArray arrayWithArray: selectedList];
[tmp replaceObjectAtIndex:[selectedList indexOfObject:selectedItem] withObject:tester];
EDIT: To clarify, __NSArrayI is a concrete immutable subclass of NSArray, __NSArrayM is a mutable one. You should not rely on the private class names, but since they speak for themselves, you can at least know which is mutable and which is not.

Related

crash while removing objects from NSMutableArray

In my iphone project (ARC enabled) i have a nsmuatble array which contains some 5 managed objects (which are retrieved from core data ) and in some scenario i need to remove all the objects from that nsmutablearray
i have used following methods to remove objects but its crashing in both the cases with the crash log -[__NSArrayI removeObject:]: unrecognized selector sent to instance 0xa391640
if (surveys && [surveys count]>0)
{
[surveys removeAllObjects];
surveys = [[NSMutableArray alloc]init];
}
and also i tried
if (surveys && [surveys count]>0)
{
for(Survey *obj_Survey in surveys)
{
[surveys removeObject:obj_Survey];
}
surveys = [[NSMutableArray alloc]init];
}
can any one tell me how do i empty that array,, any suggestions would be appreciated, thanx in advance
The answer is very simple.
For First case.
Check the part where you have initialized your array, and check if somewhere through your code, if you have assigned an NSArray to your NSMutableArray object.
For second case.
You cannot remove objects from the array while you are enumerating through it. This will result in a crash saying array has mutated while enumerating
This:
[__NSArrayI removeObject:] : unrecognized selector sent to instance 0xa391640
indicates that your array "surveys" is NSArray (not-mutable). Are you sure you have initialized it properly? If you do it by an assignment like this
NSMutableArray* surveys = [someManagedObjectContext executeFetchRequest:request]
an array "surveys" will be of type NSArray because Core Data fetch requests return NSArrays.
The error message says it all,
[__NSArrayI removeObject:]: unrecognized selector
__NSArrayI is a code-word for an immutable array (NSArray), That means your surveys object is not NSMutablArray, but NSArray.
You cannot add or remove objects from NSArray.
Check your code. You have assigned NSArray to surveys or you have reinitialized it as NSArray.
Remove all the things that you are doing and simply do like this
[surveys removeAllObjects];
As from the error that you are getting so maybe that Array is not NSmutableArray just normal array so thats why you can not remove object from It and you try to do so and app got crash
check where you have initialised it if it is Mutable or not
so as I said remove all that thing and use simple removeAllObject
From the exception it's very evident that at some point you are assigning an immutable instance to your mutable array. From the comments I could make out that you were sorting surveys and sorted array was returning immutable array. Type casting will not do good for getting mutableCopy of an immutable object.
NSArray *sortDescriptors = [[NSArray alloc] initWithObjects:sortDescriptor1,nil];
surveys = (NSMutableArray *) [[[NSMutableArray alloc]initWithArray:surveys ] sortedArrayUsingDescriptors:sortDescriptors];
Instead of it use
[surveys sortUsingDescriptors: #[sortDescriptor1]];
You might have initialised with Immutable Array.
Use the following Code:
NSMutableArray *newArray = [NSMutableArray arrayWithArray: oldArray];

Populate UITableView using NSMutableDictionary, keysSortedByValueUsingSelector

My model class has a NSMutableDictionary with my data. In my view class, I want to display that data in my UITableView cellforRowAtIndexPath method. My view class has an NSArray for the data to display.
I can do this to get my data into my NSArray to display correctly:
self.CategoriesArray = [model.CategoryDictionary allKeys];
However, since NSMutableDictionary does not sort on its own, my items in my TableView are not in alphabetical order. I thought I could do this:
However, I get the following error:
2Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSCFBoolean localizedCaseInsensitiveCompare:]: unrecognized selector sent to instance 0x13d0a20'
I'm assuming that's because my view class doesn't know what to do with the localizedCaseInsensitiveCompare method.
How do I solve this problem? Thanks.
I think you were saying that this gives you the correct results, just not in order, right?
self.CategoriesArray = [model.CategoryDictionary allKeys];
If that's the case, then this will give you the correct order if I'm understanding your question correctly:
NSArray* keys = [model.CategoryDictionary allKeys];
self.CategoriesArray = [keys sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
localizedCaseInsensitiveCompare: is only to compare NSString, not NSDictionary or NSArray.
To sort your categoriesArray look at
sortedArrayUsingComparator: and sortedArrayUsingDescriptors: for NSArray
sortUsingDescriptors and sortUsingComparator for NSMutableArray
To loop through your array you can do something like
for (NSString *string in categoriesArray)
{
}

Initializing NSMutableDictionary to create a filter

This is a continuation question I had from a post yesterday: Initializing NSMutableDictionary
(It's probably a stupid question, but I don't see what I'm doing wrong.)
I liked the idea of just having "All" listed in my TableView that pops up when the filter button is pressed in order to indicate no filter applied. I get my data from my model class sorted correctly into an NSMutableArray like so:
NSArray *anArray = [dmgr.CategoryDictionary allKeys];
self.CategoriesArray = [anArray sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)];
[self.CategoriesArray insertObject:#"All" atIndex:0]; // line causes crash
But I want to add the "All" option to the CategoriesArray to show in the UITableView. When I try to run it, it crashes at that line because of
NSArrayI insertObject:atIndex:]: unrecognized selector sent to instance 0x59baba0
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayI insertObject:atIndex:]: unrecognized selector sent to instance 0x59baba0'
Any help would be appreciated. Thanks!
sortedArrayUsingSelector: returns an immutable array which is why you can't add to it. Do this to get a mutable copy.
self.CategoriesArray = [NSMutableArray arrayWithArray:[anArray sortedArrayUsingSelector:#selector(localizedCaseInsensitiveCompare:)]];
It seems CategoriesArray is actually a NSArray instance. From Apple's doc :
-(NSArray *)sortedArrayUsingSelector:(SEL)comparator;

NSMutableArray addObjects - unrecognized-selector

This is how I initialize my NSMutablearray. I copy the content of cityList into cityArray. Both are NSMutableArray. FYI, I declared the'cityArray' using extern.
cityArray = [[NSMutableArray alloc] init];
[cityArray addObjectsFromArray:cityList];
Then, in other method in another class, I tried to to add one more object into 'cityArray' This is how I do it. But it keep crashing when it run this line of code.
NSString *allCities = #"All Cities";
[[cityArray valueForKey:#"cityName"] addObject:allCities];
This is from the console '[__NSArrayI addObject:]: unrecognized selector sent to instance 0x6292de0''.
But if I test it with setvalue:forkey:, it works but that is not what I want. I want the new data to be added into the bottom of the list.
An NSArray doesn't implement valueForKey:. Your want either an NSDictionary or use objectAtIndex:.
Your second section of code should read:
NSString *allCities = #"All Cities";
[cityArray addObject:allCities];

Remove an object in NSMutableArray?

I have a NSMutableArray like this:
NSMutableArray *array =...; (array contain my custom object)
NSMutableArray *toRemove = [array getObjectsToRemove];
But when I try to call removeObjectsInArray ( [array removeObjectsInArray:toRemove]; ) it breaks my app! Can anybody tell me how to solve my problem :(
I expect the error you are getting is "[NSMutableArray getObjectsToRemove] unrecognized selector sent to.."
NSMutableArray does not have such a method.
That's as far as I can answer without a bit more information, like the actual error message and the code for getObjectsToRemove (wherever it is defined).