UITableView with NSArray gives "index beyond bounds" error - uitableview

I have some experience with using tableviews. This time, I tried loading it from an array (well, technically, from a dictionary, but the allKeys parameter is an NSArray), however, I just get this exception
-[__NSArrayI objectAtIndex:]: index 10 beyond bounds [0 .. 9]
Now, my array is 11 keys long, which means it would be counted as 10 (since Obj-C counts 0 as well). Here it says it's count is 9. I have tried several different methods:
Moving the initialisation of the dictionary to - (void)awakeFromNib
Creating a separate NSArray with all the keys
Just listing 11
But they all give me the exception!
Update
I noticed some of you were saying that my array is only 10 objects long, but if I set it to 10, I get one object missing:
The breakpoint tells 11...
There's no "Acceleration X" item when using 10 items, see?
And NSLogsays differently than 10, in the same method as returning the amount of rows

The fact of the matter is that your array is 10 items long. The comments above aren't saying "you should remove "Acceleration X" to make it 10 items long", they're saying "you're mistaken in your belief that your array is 11 items long".
Without seeing more code, it's difficult to say what's really going on here; but anyway, you shouldn't be using -allValues, because the ordering in that array is undefined, which makes it unsuitable for use backing a table view.
Instead, you should keep an array of the keys of the dictionary in whatever order you want them to display, and then reference _items[key] directly.
For example:
_keys =
#[
#"Red",
#"Orange",
#"Yellow",
#"Green",
#"Blue",
#"Indigo",
#"Violet"
];
_dictionary =
#{
#"Blue": #"Battle",
#"Green": #"Gave",
#"Indigo": #"In",
#"Orange": #"Of",
#"Red": #"Richard",
#"Violet": #"Vain"
#"Yellow": #"York",
};
- (NSString *)labelTextForIndexPath:(NSIndexPath *)indexPath
{
return _keys[indexPath.row];
}
- (NSString *)detailLabelTextForIndexPath:(NSIndexPath *)indexPath
{
return _dictionary[_keys[indexPath.row]];
}

Related

Unable to store sqlite3_last_insert_rowid into an array

I am using the following code to store "sqlite3_last_insert_rowid" into NSMutableArray,I am getting the rowid but nothing is stored in the array. It is giving me null.
NSUInteger rowIDNum=sqlite3_last_insert_rowid(myDatabase);
NSNumber *xWrapped = [NSNumber numberWithInt:rowIDNum];
[_rowID insertObject:xWrapped atIndex:0];
NSLog(#"row ID array %#",[_rowID objectAtIndex:0]);
Could you please tell me the correct way to store rowid into an array?
I suspect the array is not allocated, else you would get an NSRangeException if the array was allocated but empty (i.e. the first time you called that method).
From the NSMutableArray reference:
index
The index in the array at which to insert anObject. This value
must not be greater than the count of elements in the array.
Important: Raises an NSRangeException if index is greater than the
number of elements in the array.
You would normally allocate the array in the class init method or viewDidLoad method, depending on what the class is. Once you've allocated the array, use:
NSUInteger rowIDNum=sqlite3_last_insert_rowid(myDatabase);
[_rowID insertObject:#(rowIDNum)];

Can I use NSMutableArray insertObjects:atIndexes to insert multiple items in different order?

I'd like to insert a range of items into an NSMutableArray in a single operation using insertObjects:atIndexes, and sort the items at the same time - but I can't figure out quite how to build the correct NSIndexSet. Something like this:
NSMutableArray* target = [[NSMutableArray alloc]initWithObjects:#0, #100, nil];
NSArray* itemsToInsert = #[#50, #10];
NSMutableIndexSet* indexes = [[NSMutableIndexSet alloc] init];
// ??? what goes in indexes?
[target insertObjects:itemsToInsert atIndexes:indexes];
XCTAssertEqualObjects((#[#0, #10, #50, #100]), target);
The apple documentation doesn't really explain how it works - it implies however that the index set is going to be processed sequentially... If that's the case, then logically I should do this:
[indexes addIndex:1]; // insert #50 at position 1
[indexes addIndex:1]; // insert #10 at position 1, pushing #50 up to position 1
The problem is, this doesn't work - the insert throws an exception with [NSMutableArray insertObjects:atIndexes:]: count of array (2) differs from count of index set (1)
I've also tried:
inserting an index range - which fails with the same exception
inserting indexes of 1, 2 - this has an incorrect result of #[#0, #50, #10, #100]
inserting indexes of 2, 1 - this also has an incorrect result of #[#0, #50, #10, #100]
Is this possible? I could solve it by pre-sorting the list of items before I insert them, but it would be nice not to have to create a temporary copy of the list
An NSIndexSet contains only "unique unsigned integers", stored "as sorted ranges". What you're trying to do with the index set just won't work.
If you used an array instead to hold your indexes, you could loop through the values and indexes in parallel and use insertObject:atIndex: repeatedly. This would be made simpler by adding a category method to NSMutableArray, such as OEInsertObjects:atOrderedIndexes: Then your first approach, repeatedly inserting at index 1, would work, although that seems strange to me because you'd always have to take the movements into account.

Problems with objectAtIndex of NSMutableArray

I am developing a game for iPhone in which I have 2 arrays.
One with the objects "living" in the game, and when these objects "die" they are placed in another array to be removed from the first one in the end of the first loop.
This is necessary because if the object dies in the loop and it is removed immediately from the first array, the index is lost and sometimes gives an invalid address access.
Then I have an NSMutableArray that contains objects to be removed from the living objects array.
In the array with objects to remove, I am constantly adding and removing items. Sometimes when I use objectAtIndex with the array with items to remove, it is retuning me other object.
For example in the first moment _enemiesToRemove has 2 objects:
([0]-> 0x0a8b5120, [1]->0x18f3a090)
for(int i = [_enemiesToRemove count] - 1; i >= 0 ; i--){
fish = [_enemiesToRemove objectAtIndex:i];
[self removeEnemy:fish];
}
and then
int i = [_enemiesToRemove count] - 1
gives i=1 but when it is doing
[_enemiesToRemove objectAtIndex:i]
it is returning me other object with address 0xbfffcd58 and it should be [1]->0x18f3a090
What is happening here, somebody knows? It is not happening always. It happens randomly.

NSRangeException - NSArrayM objectAtIndex

EDIT - SOLVED: the problem was when I created the string with all the objects to put into the tableview. I used the '?' to separe each object and one of those contained that character so the array broke.
[myString appendFormat:#"%#$%#$%#$%#?",
[currentCampeggioDict valueForKey:#"id"],
[currentCampeggioDict valueForKey:#"nome"], [...]
NS Array *elencoCampeggi=[myString componentsSeparatedByString:#"?"];
That's it.
I have this problem: my app receives from an URL a XML file with a list of objects. The tableview is populated by those objects. There are so many items, so I have to call several times the url, changing a parameter in it for example :
http://www.myurl.com?method=xxx&PAGE=1
http://www.myurl.com?method=xxx&PAGE=2
etc..
The last cell of the tableview contains the sentence "Click to load next 25 objects" and it changes the page number for the URL, delete itself and reload the url, adding the new objects to the tableview.
After 4 times everything works great, but when I press the cell for the fifth, an exception appears with the following text:
Terminating app due to uncaught exception 'NSRangeException', reason: '* -[__NSArrayM objectAtIndex:]: index 17 beyond bounds [0 .. 16]'
Any help? Thanks.
EDIT: some code: this is the part where I delete the last cell
-(void) loadTestData {
// fill moviesArray with test data
NSInteger lastRow = [CampeggiArray count]-1;
if (lastLoadedPage > 1){
[CampeggiArray removeObjectAtIndex:lastRow];
[self.tableView reloadData];
}
[...]
Issue is because you are returning wrong row count in your tableview delegate method. You need to identify the total no of objects to be listed in the tableview and return the count in your tableview delegate method. This is not your page size.
For each hit you need to keep on appending the new objects to the already existing datasource(NSArray) and reload the table.There will be no objects in the datasource during initial hit.
I guess, you are returning 16 instead of 15 in the delegate method, so you wil get crash with exception. Don't hard code values in your delegate method, just get the total number of objects(entire set) and return the count of it.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
return [totalObjects count];
}

xcode check if there is aobjectAtIndex or check array length

I cant find this any where, I may be searching the wrong terms or words but I just need to know how to check if an array is a certain length:
if ([scores objectAtIndex:3]){
//code
}
This comes up with an error and crashes if the array isnt this long yet, but surly this should just check if there is an index, and if not move on??
How to I check this without the app crashing??
count method of NSArray returns the number of objects in the array. If [myArray count] returns n then valid indexes are 0 to n - 1. There is no automatic move on if the index is not valid. Before trying to access an index you need to make sure that the index is valid.
if ([scores count] >= 4) {
id obj = [scores objectAtIndex:3];
}

Resources