NSMutable Array beyond bounds - iphone

I have a block of code which when executed gives me this error. And I am relatively new, I can't seem to fix the problem.
Error:
2011-09-06 12:31:06.094 ForceGauge[266:707] CoreAnimation: ignoring exception: * -[NSMutableArray objectAtIndex:]: index 1 beyond bounds [0 .. 0]
-(void)peakCollector:(NSMutableArray *)testarray {
NSUInteger totalRows = [testarray count];
NSMutableArray *percentArray = [[NSMutableArray alloc]initWithObjects:0, nil];
if(forcecontroller.selectedSegmentIndex==0)
testarray = lbData;
else if(forcecontroller.selectedSegmentIndex==1)
testarray = kgData;
else if(forcecontroller.selectedSegmentIndex ==2)
testarray = ozData;
else if(forcecontroller.selectedSegmentIndex ==3)
testarray = newtonData;
for(int i = 0; i< totalRows-1; i++) {
if ([[testarray objectAtIndex:i+1] doubleValue] >= 1.2 * [[testarray objectAtIndex:i] doubleValue]) {
percentArray = [testarray objectAtIndex:i];
DatabaseTable *tableVC = [[DatabaseTable alloc] initWithStyle:UITableViewStylePlain];
[self.navigationController pushViewController:tableVC animated:YES];
if(forcecontroller.selectedSegmentIndex==0)
[tableVC copydatabase:percentArray];
else if(forcecontroller.selectedSegmentIndex==1)
[tableVC copydatabase:kgData];
else if(forcecontroller.selectedSegmentIndex==2)
[tableVC copydatabase:ozData];
else if(forcecontroller.selectedSegmentIndex==3)
[tableVC copydatabase:newtonData];
[tableVC release];
} else {
[analogData removeAllObjects];
}
}
}

There are multiple issues here:
1) NSArrays can only contains NSObjects.
In your code, you are initializing your NSArray using [[NSMutableArray alloc]initWithObjects:0, nil];, but 0 is an atomic type, not an NSObject
(and basically 0 is the same value as nil (nil and NULL are typically equal to 0, interpreted as the id and void* types, respectively)
You have to encapsulate your 0 value in an NSNumber instead :
[[NSMutableArray alloc]initWithObjects:[NSNumber numberWithInt:0], nil];
Then retrieve the NSNumber using [percentArray objectAtIndex:0] and finally convert back the retrieve NSNumber to int using NSNumber's intValue method:
NSNumber* number = [percentArray objectAtIndex:0]; // returns an NSNumber which is an NSObject encapsulating numbers, see Apple's documentation
int val = [number intValue]; // retrieve the integer value encapsulated in the NSNumber
// or directly:
// int val = [[percentArray objectAtIndex:0] intValue];
2) The exception you got is in fact elsewhere and is much more subtle: you are retrieving the [testarray count] value in an NSUInteger variable, which is an unsigned type. Then totalRows-1 will do some tricky things if totalRows is equal to 0 (which is obviously the case considering the exception you have).
As totalRows is an NSUInteger, when it is equal to 0, totalRows-1 will not be equal to -1, but to... (NSUInteger)-1 (-1 interpreted as an unsigned integer), which is 0xFFFFFFFF, or namely the maximum value of the NSUInteger type!
This is why i is always less than this totalRows-1 value (as this value is not -1 but 0xFFFFFFFF = NSUInteger_MAX).
To solve this issue, cast your totalRows variable to an NSInteger value, or add a condition in your code to treat this special case separately.

Please check the how many objects test array contains at beginning of for loop.
Other thing that can help is that avoid NSUInteger and use simple int for storing array count.
Please post if this don't work.

The error simply means that you're trying to retrieve an object at an index that does not exist. In your specific case, the array you're trying to get the object from does not have an object at index 1
An easy example
[0] => MyCoolObject
[1] => MySecondObject
[2] => ObjectTheThird
You can access indexes 0,1,2 of your array as they contain objects. If you now would try to access index 3 it would throw the Out of bounds exception as index 3 does not exist.

Related

Working with ObjectAtIndex gives beyond bounds error

I want to do something really simple but I get an error, what I'm missing?
int i;
int count;
TutorialAppDelegate *appDelegate = (TutorialAppDelegate *)[[UIApplication sharedApplication] delegate];
Animals *aAnimal = (Animals *)[appDelegate.animals objectAtIndex:i];
count = [animals count];
if (i < count)
{
NSLog(#"%#",aAnimal.animalName);
}
ERROR:
'*** -[NSMutableArray objectAtIndex:]: index 22510243 beyond bounds [0 .. 5]'
The 0...5 is correct! There are only 6 values in the array.
And use
NSLog(#"%#",aAnimal.animalName);
out of the if function returns the right value, when I also change the i to 0 ofcourse.
You need to initialise i.
int i = 0;
By default ints are not set to zero or anything sensible. You can check this by adding a line such as:
NSLog(#"Value of i without initialising is: %d", i);
please intialise your mutable array-
appDelegate.animals=[[NSMutableArray alloc] initWithArray:(NSArray *)array];
and check out your array, have you mention nil object at the end of your array elements-
NSMutableArray* animals=[[NSMutableArray alloc]
initWithObjects:#"one 1",#"two 2",nil];

Gather the count of a specific object from NSMutableArray

Hey guys & girls,
Im wondering how I can find the object count of a specific type of object in an array.
For example, i have 6 'clouds' in NSMutableArray at random locations, I also have 4 'dragons' in this NSMutableArray.
How can i gather the integer 6?
I was thinking something along the lines of:
int z = [[SomeClass *clouds in _somearray] count];
Any assistance would be greatly appreciated.
Thnx,
Oliver.
Yet another way is in using blocks:
Class cloadClass = NSClassFromString(#"Cloud");
NSArray *a = /* you array with clouds and dragons */;
NSIndexSet *clouds = [a indexesOfObjectsPassingTest:
^(id obj, NSUInteger idx, BOOL *stop) {
return [obj isKindOfClass:cloadClass];
}];
// now we can count clouds
NSLog(#"%d", [clouds count]);
// but also we now can return our clouds immediately and
NSLog(#"%#", [a objectsAtIndexes:clouds]);
int result = 0;
for (NSObject *object in _somearray) {
if ([object isKindOfClass:[SomeClass class]])
result++;
}
result is the count you are looking for
If you're looking for how many times a specific instance of an object appears, you can do:
NSCountedSet *counts = [NSCountedSet setWithArray:myArrayOfObjects];
NSUInteger count = [counts countForObject:myObject];
Otherwise you'd just have to loop through the array manually and count.

how do I create fresh NSMutableArray?

I have an NSMutableArray which only lasts during the session.
Currently I create it like this
NSMutableArray *temp = [[NSMutableArray alloc] initWithCapacity:10];
[self setScoreArray:temp];
[temp release];
Problem is when I go to check each index I'm getting an array outofbounds error
NSNumber *previousScore = [[self scoreArray] objectAtIndex:[self quizNum]];
if ( previousScore != nil )
{
[self clearQuizBtns];
NSInteger previousScoreValue = [previousScore integerValue];
[self selectButtonAtTag:previousScoreValue];
}else {
[self clearQuizBtns];
}
I've read in other posts that initWithCapacity doesn't actually create the array. So what can I populate the array with initially?
Thanks in advance.
Two ways:
first: to initiate array with default values of NSNull class
NSMutableArray *temp = [[NSMutableArray alloc] initWithCapacity:10];
for (int i = 0 ; i < 10 ; i++)
{
[temp insertObject:[NSNull null] atIndex:i];
}
[self setScoreArray:temp];
[temp release];
and then to check: if object is kind of NSNull class means it was a never set before
id previousScore = [[self scoreArray] objectAtIndex:[self quizNum]];
if (![previousScore isKindOfClass:[NSNull class]])
{
[self clearQuizBtns];
NSInteger previousScoreValue = [(NSNumber *)previousScore integerValue];
[self selectButtonAtTag:previousScoreValue];
}else {
[self clearQuizBtns];
}
second: store scores in NSMutableDictionary and use NSNumber's as keys
// scoreDictionary property of NSMutableDictionary class must be declared in self
NSNumber *previousScore = [self.scoreDictionary objectForKey:[NSNumber numberWithInt:[self quizNum]]];
if (previousScore != nil)
{
[self clearQuizBtns];
NSInteger previousScoreValue = [previousScore integerValue];
[self selectButtonAtTag:previousScoreValue];
}else {
[self clearQuizBtns];
}
NSArray does not support "holes". The capacity is just a hint to the initializer.
You could either fill the array with placeholder objects or, more typically, change your algorithm to either fully prepopulate the array or to lazy load it linearly.
Your problem seems to be that you're never actually setting any score in the score array.. are you? NSArrays have an actual count of items in them, and accessing an index beyond that count will blow up, as you've seen. If there will only ever be a fixed (small) number of scores, like 10, then you could set them all initially to something default like:
for (int i = 0; i < 10; i++) {
[temp addObject:[NSNumber numberWithInt:0]];
}
P.S. -initWithCapacity does "create the array", it just doesn't create any objects in the array. The capacity is a hint only.
Using the arrayWithObject: or arrayWithObjects: methods can provide an array with pre-populated values.
One cool thing about NSMutableArrays is that you can just do an "init" and the array will handle adding and removing objects on the fly. Remember that you generally addObject: or removeObjectAtIndex: when dealing with mutable arrays.

NSInteger to NSArray iPhone

I have NSInteger variable, for example NSInteger example=1256 and i need an array with elements of this variable.
so first element of array is array[0] = 1
array[1] = 2
array[2] = 5 etc..
what way can i solve it ?
Here's about how I'd do it:
NSUInteger number = 1234567890;
NSMutableArray * numbers = [NSMutableArray array];
while (number > 0) {
NSUInteger lastDigit = number % 10;
[numbers insertObject:[NSNumber numberWithUnsignedInteger:lastDigit] atIndex:0];
number = number / 10;
}
You need to use NSMutableArray to be able to change entries. NSMutableArray can only hold objects, not primitive types like NSInteger. Also, if you are using NSMutableArray, you can't access the elements the same way as with a C array.
[array insertObject:[NSNumber numberWithInteger:2] atIndex:1];
You can convert your integer to a char* then iterate through it casting each character back to an int and adding it to a C array or, as Steven says, an NSArray of NSNumbers.

NSMutable Array

I have a NSMutableArray:
NSMutableArray *temp = //get list from somewhere.
Now there is one method objectAtIndex which returns the object at specified index.
What I want to do is that, I want to first check whether an object at specified index exists or not. If it exists than I want to fetch that object. Something like:
if ([temp objectAtIndex:2] != nil)
{
//fetch the object
}
But I get exception at the if statement saying that index beyond bound.
Please anyone tell me how to achieve this.
you cannot have 'empty' slots in an NSArray. If [myArray count]==2 ie array has two elements then you know for sure that there is an object at index 0 and an object at index 1. This is always the case.
Check the length first using the count method.
if ([temp count] > indexIWantToFetch)
id object = [temp objectAtIndex:indexIWantToFetch];
you could do this way:
When you initialize, do something like:
NSMutableArray *YourObjectArray = [[NSMutableArray alloc] init];
for(int index = 0; index < desiredLength; index++)
{
[YourObjectArray addObject:[NSNull null]];
}
Then when you want to add but check if it already exists, do something like this:
YourObject *object = [YourObjectArray objectAtIndex:index];
if ((NSNull *) object == [NSNull null])
{
/// TODO get your object here..
[YourObjectArray replaceObjectAtIndex:index withObject:object];
}
Just check that the index is >= 0 and < count
Returns the number of objects currently in the receiver.
- (NSUInteger)count
int arrayEntryCount = [temp count];
First of all you check the length of array-
NSMutableArray *temp = //get list from somewhere.
now check-
if(temp length)
{
Your objectclass *obj = [temp objectAtIndex:indexnumber];
// indexnumber is 0,1,2 ,3 or anyone...
}