NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 0 beyond bounds for empty array - ios

Well, I know the cause of the error, my question here is how to avoid this kind of error. In my case, what I want is, if the user enters a wrong id which means when the array return 0 results, is says for example :
NSLog (#"The id you entered is false !");
else, it proceeds the code normally without crashing.
Any ideas on how I can solve it ?

id array = [dataDictionary objectForKey:#"routes"];
if([array count] == 0) {
NSLog(#"don't access it as the index is out of bounds);
return;
}

Related

NSNumber storing objects of NSDictionary in Objective-C

My iOS app terminates with Thread 1: signal SIGABRT error. The strange thing is, when I hover the cursor over the NSNumber object (where the error has occurred), it displays the objects of an NSDictionary with Key/Value pair. Following is my code snippet:
for(id obj in [MainDict allKeys])
{
NSArray *AnArrayInsideMainDict = [MainDict objectForKey:obj];
double i=1;
for(NSUInteger n=0; n<4; n++)
{
NSNumber *anObject = [AnArrayInsideMainDict objectAtIndex:n];
NSNumber *nextObject = [nextDict objectForKey:[NSNumber numberWithDouble:i]];
NSNumber *HereIsTheError = [NSNumber numberWithFloat:(powf(([anObject floatValue]-[nextObject floatValue]),2))];
[ThisIsMutableArray addObject:HereIsTheError];
i++
}
}
Here, the MainDict contains 64 key/value pairs (each key contains an NSArray of 5 objects).nextDictis an NSDictionary with 4 key/value pairs (each key contains one NSNumber object // EDIT: each key actually contained an NSArray with single NSNumber Object, this was the reason for the error). After the app termination and hovering the cursor over the HereIsTheError, I get following key/value pair:
The terminating error at the console is:
*** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayM floatValue]: unrecognized selector sent to instance 0x170257a30'
*** First throw call stack:
(0x18b032fe0 0x189a94538 0x18b039ef4 0x18b036f54 0x18af32d4c 0x1000891a0 0x10008bd74 0x10020d598 0x100579a50 0x100579a10 0x10057eb78 0x18afe10c8 0x18afdece4 0x18af0eda4 0x18c979074 0x1911c9c9c 0x1000906b4 0x189f1d59c)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
How can NSNumber conation the objects of NSDictionary? I use Xcode Version 9.0.1 (9A1004) and Objective-C.
As the comments state, but most importantly your error message states, your objects anObject and nextObject are not NSNumber's - they are NSMutableArray's, hence the
-[__NSArrayM floatValue]: unrecognized selector...
part of your error.
Ensure the objects in AnArrayInsideMainDict are in fact
NSNumber's before attempting to cast them as numbers,
I would suggest flagging your objects before "assuming" their types, but I doubt that would help you get your desired outcome (as this would most likely from your case here skip each object that is not an NSNumber).
Before you even enter the for loop in [MainDict allKeys], backtrace to make sure you are in fact passing arrays of NSNumber's as the dictionaries objects.
IF you are actually not sure of the object types, you can just throw a flag to make sure you are not misinterpreting any of the objects:
...
for (NSUInteger n=0; n<4; n++) {
NSNumber *anObject = [AnArrayInsideMainDict objectAtIndex:n];
NSNumber *nextObject = [nextDict objectForKey:[NSNumber numberWithDouble:i]];
if ([anObject isKindOfClass:NSNumber.class] && [nextObject isKindOfClass:NSNumber.class]) {
// Good to continue now that you know the objects
} else NSLog(#"whoops.. anObject: %# nextObject: %#", anObject.class, nextObject.class);
...
LASTLY, if you are so daring, and are sure that somewhere in this dictionary are your NSNumber's, you could flag your steps to check for instances of the NSNumber.class in order to seek out your floats.
Otherwise, I suggest deep diving into the how and where you are getting your MainDict from.
Happy coding - cheers!

Loop through array then compare current object to string

I'm trying to iterate through an NSArray and check if an objectAtIndex is equal to a string.
NSLog(#"%#", myArray) // 3 items. 1 of them is "a"
for (id object in myArray)
{
NSLog(#"What"); // 3 times
if ([object isEqual:#"a"]) {
NSLog(#"Hello"); // Never gets executed
}
}
The problem is, the NSLog in the if statement never gets executed?
Edit
(
(
a
),
(
01
),
(
a
),
(
03
)
)
When I set it to isEqualToString, I get this error:
2015-03-30 14:42:54.206 MyApp[1575:50954] -[__NSArrayM isEqualToString:]: unrecognized selector sent to instance 0x7fe721ce3bf0
2015-03-30 14:42:54.215 MyApp[1575:50954] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSArrayM isEqualToString:]: unrecognized selector sent to instance 0x7fe721ce3bf0'
Your problem is that you have an array that contains three sub-arrays, each of which contain, what is presumably, a single string. You can tell this because of the extra ()'s around the strings in the log output, and by the fact that it's telling you that you tried to send a selector to __NSArrayM.
Here is a quick fix:
NSLog(#"%#", myArray) // 3 items. 1 of them is "a"
for (NSArray *array in myArray)
{
NSLog(#"What"); // 3 times
if ([array.firstObject isEqualToString:#"a"])
{
NSLog(#"Hello"); // Never gets executed
}
}
But as others have pointed out you probably want to use isEqualToString: since it will be more performant.
You may also want to reconsider the code that is generating this nested array structure, or the schema that you're using in general, because it seems... unnecessary. Without further information there's not much to be done.

[__NSCFBoolean count]: unrecognized selector : Best way to prevent this crash

I am getting this error on the conditional if statement. Is there a good way to prevent this error from showing up? Any tips or suggestions are appreciated. I am guessing subanswer for some reason is a boolean.
id subAnswer = [answer objectForKey:#"answer"];
NSArray *subAnswerKeyList;
if (subAnswer != [NSNull null] && subAnswer != nil && [subAnswer count] > 0 ) {
...
}
Replace your if statement with:
if ([subAnswer isKindOfClass:[NSArray class]] && [subAnswer count]) {
}
Your subAnswer is actually a number representing a BOOL value. You need to see why you expect it to be an array.
your "subAnswer" object is almost certainly not the NSArray object you're expecting it to be.
Put a "NSLog("subAnswer is %#", subAnswer);" in your code there and your Xcode console will tell you what the object really is.

Updating a value in an NSMutable Array

I am trying to update a specific key in an NSMutableArray. The array is called ListForTable and I am trying to update the key statusReport. There are 4 objects in the array. I am trying to update the first.The following is causing an error:
[ListForTable replaceObjectAtIndex:[[ListForTable objectAtIndex:0] objectForKey:#"statusReport"] withObject:#"No edits"];
The array is created in the following way:
[ListForTable addObject:[NSDictionary dictionaryWithObjectsAndKeys: itemName, #"itemName", #"", #"statusReport", nil]];
Can anyone explain why?
The error message is:
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM replaceObjectAtIndex:withObject:]: index 1087320 beyond bounds [0 .. 3]'
*** First throw call stack:
(0x2c57df87 0x39f1ac77 0x2c49b331 0xbe9bb 0x2f9fc86d 0x2f9fc5dd 0x300511f7 0x2fcc5b51 0x2fcdd933 0x2fcdf8cb 0x2fadc615 0xab051 0x2fa2d497 0x2fa2d439 0x2fa1804d 0x2fa2ce69 0x2fa2cb43 0x2fa26451 0x2f9fccc5 0x2fc70513 0x2f9fb707 0x2c544807 0x2c543c1b 0x2c542299 0x2c48fdb1 0x2c48fbc3 0x337c4051 0x2fa5ba31 0x604d5 0x3a4b6aaf)
libc++abi.dylib: terminating with uncaught exception of type NSException
This is an error:
[ListForTable replaceObjectAtIndex:[[ListForTable objectAtIndex:0] objectForKey:#"statusReport"] withObject:#"No edits"];
You are getting your parameters mixed up.
[ListForTable replaceObjectAtIndex:...]
should be taking an integer
But
[[ListForTable objectAtIndex:0] objectForKey:#"statusReport"]
is probably not an integer.
Rather than replace it, get the pointer to it:
NSMutableDictionary *entry = [[ListForTable objectAtIndex:0] mutableCopy];
and update it:
entry[#"statusReport"] = #"No edits";
and then replace:
[ListForTable replaceObjectAtIndex:0 withObject:[entry copy]];
Logic being: you can't modify an NSDictionary (it is immutable) so you need a mutable copy that you can change. Once you change it, you need to replace it.
the
[entry copy]
bit makes it an immutable dictionary again.
Truthfully, it doesn't look like you want this array to contain immutable objects anyway, but I hope this explains your issues
[ListForTable replaceObjectAtIndex:
[[ListForTable objectAtIndex:0] objectForKey:#"statusReport"]
withObject:#"No edits"];
Second line is your "index" but it appears to be an object of some sort.
Trying to parse your intention, I'm thinking maybe you aren't trying to do:
ary[0] = "something else";
You are trying to modify something in the array?
If so you probably want to do something more like this:
MyCoolObject *o = [ListForTable objectAtIndex: 0];
[o setSomethingOrOther: #"No Edits"];
However if you were just trying to swap out something in the array. You need to do something like:
[ListForTable replaceObjectAtIndex: 0 withObject: #"whatever!"];
Don't call this while iterating over your array. Also don't name a variable starting with a capital letter.
You want to do:
[[ListForTable objectAtIndex: 0] setObject:#"no edits" forKey:#"statusReport"];

how to add object at specific index and also remove another object from NSMutableArray?

hello friends i'm new in ios development.
i want to add object at specified index for that i code here.
arrNotificationTime = [NSMutableArray arrayWithCapacity:arrNotificationView.count];
for (int i=0; i<arrNotificationView.count; i++)
{
[arrNotificationTime addObject:[NSNull null]];
}
NSLog(#"Time count == %d",[arrNotificationTime count]);
[arrNotificationTime replaceObjectAtIndex:btnNotificationTime.tag withObject:btnNotificationTime.titleLabel.text];
and it work perfectly but i also want to remove another or the same object from this array or also print this array is not work for that i code here.
NSLog(#"arrNotificationTime == %#",arrNotificationTime);
[arrNotificationTime removeObjectAtIndex:[btn tag]];
when i nslog the array it will crash the application.
The error report is.
2014-05-13 17:52:09.973 TOPDesign[1057:11303] arrNotificationTime count = 0
2014-05-13 17:52:09.974 TOPDesign[1057:11303] arrNotificationTime == (
)
2014-05-13 17:52:09.975 TOPDesign[1057:11303] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM removeObjectAtIndex:]: index 1 beyond bounds for empty array'
*** First throw call stack:
(0x15ae012 0x12bbe7e 0x15501c4 0xc6ec 0x12cf705 0x2032c0 0x203258 0x2c4021 0x2c457f 0x2c36e8 0x4c71d3 0x1576afe 0x1576a3d 0x15547c2 0x1553f44 0x1553e1b 0x260f7e3 0x260f668 0x1ffffc 0x2592 0x24c5)
libc++abi.dylib: terminate called throwing an exception
(lldb)
You can't remove any object in empty array. so it crashes.
you must use like this
[arrNotificationTime count] is total count of your array
suppose you have 10 items
you btn tag should be within 0 to 9. if you access the 11th item then it will crash. to avoid it. you must use like this
if([arrNotificationTime count]>[btn tag]){
[arrNotificationTime removeObjectAtIndex:[btn tag]];
}
This is for adding object in specific index in array.
[YourArray insertObject:#"" atIndex:0];
This is for remove object at specific object.
[YourArray removeObjectAtIndex:5];
Hope this code is useful for you.
In your arrNotificationTime array no object and you remove the object.so app is crashed.

Resources