app is crashing on second run through of loop with nsnull count - ios

I have a loop that works fine the first time through but the second time through the loop I get:
-[NSNull count]: unrecognized selector sent to instance 0x3a094a70
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[NSNull count]: unrecognized selector sent to instance 0x3a094a70'
Here is the part in my code where I know it is crashing (the last line):
...
NSLog(#"dict::%#",dictForPost);
// collect the photo urls in an array
photosInDict = [NSArray array];
// photos is an array of dictionaries in the dictionary
photosInDict = dictForPost[#"photos"];
if (photosInDict.count) {
....
I know that when photosInDict doesnt have pictures in the dic it crashes but I dont get why since I initiated the array above it.

photosInDict = dictForPost[#"photos"]
replaces the object previously allocated and stored in photosInDict.
Therefore it does not make sense to allocate the array before. Just
NSArray * photosInDict = dictForPost[#"photos"];
and then check
if ([photosInDict isKindOfClass:[NSArray class]]) {
// Yes, it is an array. Do something with it.
if ([photosInDict count]) {
...
}
}

The result of dictForPost[#"photos"]; is giving you an NSNull object, not an array.
One option would be this:
NSLog(#"dict::%#",dictForPost);
// collect the photo urls in an array
// photos is an array of dictionaries in the dictionary
photosInDict = dictForPost[#"photos"];
if ([photosInDict isKindOfClass:[NSArray class]] && photosInDict.count) {
The line:
photosInDict = [NSArray array];
is pointless and should be removed.

You initialize photosInDict with an empty array, but then you overwrite it with the dictionary's value for "photos", which just happen to be NSNull. You need to check why your dictionary does not have an array for that key.
If the value can be NSNull depending on the situation, you must check whether it is an array or not before trying to count or taking some other action.

Related

Making a mutable array from plist

I'm trying to make an NSArray from a key in save data and make it mutable. Here's what I have so far:
NSMutableArray *availableThemes = [[[saveData valueForKey:#"availableThemes"] array] mutableCopy];
If I'm correct, sending array makes this object returned by availableThemes an array with the contents of the object, and then mutableCopy makes this array a NSMutableArray. Sadly, and obviously, I'm not. I get this error:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFArray array]: unrecognized selector sent to instance 0x786c7430'
Here, I thought, sending array would turn this data into a NSArray. Instead, it causes a complier error. I know I did something stupidly wrong. Question is, what did I do?
You are calling the class method array on an instance of NSArray.
NSMutableArray *availableThemes = [[[saveData valueForKey:#"availableThemes"] array] mutableCopy];
From your crash log it is clear that the availableThemes key returns an NSArray object, so change your code to:
NSMutableArray *availableThemes = [[saveData valueForKey:#"availableThemes"] mutableCopy];

mutating method sent to immutable object' in nsmutablearray

I want to remove objects from NSmutableArray can one tell me the Best way to remove from NSMutableArray
.h
#property(nonatomic,retain)NSMutableArray *arr_property;
.m
_arr_property=[[NSMutableArray alloc]init];
MTPop *lplv = [[MTPop alloc] initWithTitle:SelectProperty(APP_SHARE.language)
options:[_arr_property valueForKeyPath:#"property_list.property_type_name"]
handler:^(NSInteger anIndex) {
txt_Property.text=[[_arr_property valueForKeyPath:#"property_list.property_type_name"] objectAtIndex:anIndex];
NSLog(#"index number %ld",(long)anIndex);
remove object--->>>
NSLog(#"index number %#",[_arr_property valueForKey:#"property_list"]);
[[_arr_property valueForKeyPath:#"property_list.property_type_name"] removeObjectAtIndex:anIndex]; ////hear the app is crashing
app is crashing error iam getting is
2015-06-09 13:21:31.104 Estater[2170:62264] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: '-[__NSCFArray removeObjectAtIndex:]: mutating method sent to immutable object'
Think about your code:
_arr_property=[[NSMutableArray alloc]init];
You now have an empty NSMutableArray. It has no elements.
[... removeObjectAtIndex:0];
What did we just say? The array has no elements. It has no element 0 - to have an element 0 it would need to have one element at least, but it doesn't. There is nothing to remove.
[_arr_property valueForKeyPath:#"property_list.property_type_name"]
That part is the weirdest, but let's carry on. When called on an array, valueForKeyPath: results in an NSArray - not an NSMutableArray. So this gives you an empty NSArray. But you cannot say removeObjectAtIndex: to an NSArray, even if it empty - it is not mutable. That's the crash you are experiencing.
The real error is that you are calling removeObject on an element of your NSMutableArray:
[-->[_arr_property valueForKeyPath:#"property_list.property_type_name"]<-- removeObjectAtIndex:0];
The array looks empty, but if filled with something, to remove the first element you should do instead:
[_arr_property removeObjectAtIndex:0];
Firstly, you cannot work with NSMutableArray for key value coding it does not support. You must better use NSMutableDictionary for it.
As dictionaries store objects based on a key, whereas arrays store objects based on an index.
You can use NSMutableDictionary like this:
NSMutableDictionary *dict = [NSMutableDictionary dictionary];
[dict setObject:something forKey:#"Some Key"];
// ... and later ...
id something = [dict objectForKey:#"Some Key"];
Secondly, valueForKeyPath: returns a value not array and valueForKey: returns array of value for the key and also that array is not mutable.
Edit:
Thirdly, after researching more on valueForKeyPath:, found its use in collection operation and syntax for using is. So, do it by changing
[_arr_property valueForKeyPath:#"property_list.property_type_name"]
To
[_arr_property valueForKeyPath:#"#property_list.property_type_name"]

Trying to take objects out of an array, reverse them, and put them back in

as the title says I'm having an issue with taking objects out of an array, flipping them, and putting them back in. Below is the code I currently have that ends in this error
Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayI removeObjectsAtIndexes:]: unrecognized selector sent to instance
I was wondering if anyone knew how to fix this? Here's a little more info on how I have it set up:
The object "PEG" is an NSString that displays "-0.6", "4.36"
GlobalSortedArray is an array filled with dictionary containing the PEG object
//Declare variables
NSMutableArray *negArray = [[NSMutableArray alloc]init];
NSMutableIndexSet *index = [[NSMutableIndexSet alloc]init];
int negcount = 0;
NSDictionary *forLoopDict;
for (forLoopDict in globalSortedArray)
{
if ([[forLoopDict objectForKey:#"PEG"] hasPrefix:#"-"])
{
[index addIndex:negcount];
}
negcount++;
}
NSLog(#"%#", negArray);
// Removes objects from main array. This is what seems to be messing up.
[globalSortedArray removeObjectsAtIndexes:index];
// Reverses the array
NSArray* reversedArray = [[negArray reverseObjectEnumerator] allObjects];
// insters them back into the main array
[globalSortedArray insertObjects:negArray atIndexes:0];
You are trying to remove an item from globalSortedArray. It is an NSArray and not mutable.
globalSortedArray as NSmutableArray
NSArray -- > NSMutableArray

App Crashing: Mutating method sent to immutable object

I am trying to add an object to an NSMutableArray. Initially I assign some response data to the array, and can display it in a table view. After loading more data, it seems to be crashing when trying to add the new information to my original array.
I am using AFNetworking for this:
[operation setCompletionBlockWithSuccess:^(AFHTTPRequestOperation *operation, id responseObject) {
if(!_myArray){
_myArray = [responseObject objectForKey:#"data"];
}
else{
[_myArray addObject:[responseObject objectForKey:#"data"]];
}
[self.tableView reloadData];
}
The error I am getting is as follows
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException',
reason: '-[__NSCFArray insertObject:atIndex:]: mutating method sent to immutable object'
Can anybody help out with this?
The object you're retrieving from the responseObject dictionary is most likely not an NSMutableArray, but an (immutable) NSArray. You have to create a mutable copy to be able to change it:
//...
if (!_myArray) {
_myArray = [[responseObject objectForKey:#"data"] mutableCopy];
}
//...
It sounds like AFNetworking generates immutable objects. You should call -mutableCopy instead of just assigning the result of -objectForKey: directly.
Also are you really intending to have a bunch of nested arrays? It seems like it would make more sense if you added the contents of the response array, rather than the array itself.
You need to make the copy of your array. After that you have to modify that array using, [NSMutableArray arrayWithArray: ]
Your array is must be mutable array
Use NSMutablearray instead NSArray

Why am I getting "[__NSArrayI allKeys]: unrecognized selector sent to instance" / why is NSDictionary transforming?

Looking this [__NSArrayI allKeys]: unrecognized selector sent to instance error up, it seemingly occurs when you send an NSArray the allKeys message which is meant for NSDictionary, but in this case I'm very clearly sending it to an NSDictionary.
Here's the code I use when interfacing with the Pocket API:
NSDictionary *articles = [response objectForKey:#"list"];
// Create an array we can use to sort the keys (and thus the articles) in order of when they were added
NSMutableArray *allKeys = [[articles allKeys] mutableCopy];
The last line there causes the error. But articles is very clearly declared as an NSDictionary? Why is it not liking it?
Oddly enough, if I inspect it at runtime it says it's an NSArray! Why did it change?
(lldb) po articles
$5 = 0x082103e0 <__NSArrayI 0x82103e0>(
)
(lldb) po [articles class]
$6 = 0x01b83b8c __NSArrayI
(lldb)
It may be declared in your code as a dictionary, but that doesn't make it a dictionary. It is truly an array and that is why you get the exception. Check your response so you know what you should expect.
Your code compiles because the compiler doesn't know that it's going to be an array and it trusts you that it will be a dictionary. It does this because objectForKey: returns id.

Resources