I have UITableView which dataSource change by selecting UISegmentControl's segment. It has only 2 segments and for both states I load data asynchronously first time into 2 different arrays "firstTypeNotificationsArray" and "secondTypeNotificationsArray". The main array is dataSource for UITableVIew which has data from one of arrays each time and it named "allNotificationsArray".
Change main dataSource data method
-(void)changeNotificationsByType:(BOOL)firstType{
[allNotificationsArray removeAllObjects];
if(firstType){
[allNotificationsArray addObjectsFromArray:firstTypeNotificationsArray];
} else {
[allNotificationsArray addObjectsFromArray:secondTypeNotificationsArray];
}
[notificationsTable reloadSections:[NSIndexSet indexSetWithIndex:0]
withRowAnimation:UITableViewRowAnimationFade];
}
Before call method changeNotificationsByType I check my arrays count to be !=0 but I get an NSRangeException after calling.
numberOfRowsInSection method
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return allNotificationsArray.count;
}
I tried to call reloadSections in main thread with dispatch_async but it didn't help. I've also tried to do reloadData instead and no result.
Here is a crash log:
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 60 beyond bounds [0 .. 0]'
*** First throw call stack:
(0x265ec87b 0x3832adff 0x26502633 0xfcb9f 0x196879 0x3ee4a5 0x1a9dd17 0x1a9dd03 0x1aa27c9 0x265af555 0x265ada4f 0x26500129 0x264fff1d 0x2fac7af9 0x2a9889bd 0x10cc6d 0x38a78873)
libc++abi.dylib: terminating with uncaught exception of type NSException
This crash raise after switching UISegmentControl and calling changeNotificationsByType respectively. All arrays are not empty at this moment and I can't understand why my app is crashing.
Related
I have a UICollectionView in my iOS application. I'd like to use the various insert... methods to add data, primarily for the animations provided by iOS when using these methods (instead of reloadData:).
If I try to add a section, however, I get an exception from iOS. My code is extremely straightforward:
_regions = [NSMutableArray array];
[self.collectionView reloadData];
NSLog (#"Before attempting to add section, collection view has %ld sections", [self numberOfSectionsInCollectionView:self.collectionView]);
[_regions addObject:#"First Region"];
[self.collectionView insertSections:[[NSIndexSet alloc] initWithIndex:0]];
NSLog (#"After attempting to add section, collection view has %ld sections", [self numberOfSectionsInCollectionView:self.collectionView]);
So I add an object to my _regions array, which I use to implement the data source, then I call insertSection. My first NSLog works:
2015-03-24 11:25:39.052 MyApp[63858:17968323] Before attempting to add section, collection view has 0 sections
but then iOS throws an exception:
2015-03-24 11:25:42.082 MyApp[63858:17968323] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of sections. The number of sections contained in the collection view after the update (1) must be equal to the number of sections contained in the collection view before the update (1), plus or minus the number of sections inserted or deleted (1 inserted, 0 deleted).'
I implement numberOfSectionsInCollectionView in pretty straightforward manner:
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
{
return _regions.count;
}
If I reverse the calls (call insertSections before adding the string to the _regions array), I get a different exception:
2015-03-24 11:33:17.472 MyApp[63965:18001840] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to insert section 0 but there are only 0 sections after the update'
When should I modify (add an element to) _regions, relative to when I add the section to the UICollectionView?
Thanks so much for any help from experienced UICollectionView programmers . . .
*** Terminating app due to uncaught exception 'NSRangeException', reason: '
*** -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array'
*** First throw call stack:
(0x276b2fef 0x35ba6c8b 0x275c5841 0xe78bb 0xfe689 0x2b19e281 0x2b19ebab 0x2aedc981 0x2b19ea63 0x2b19f1b3 0x2afac2df 0x2b1943a7 0x2afa34d7 0x2aecd003 0x2a8eefc1 0x2a8ea7fd 0x2a8ea685 0x2a8ea031 0x2a8e9e1f 0x2a8e3b79 0x27678ffd 0x276766bb 0x27676ac3 0x275c3221 0x275c3033 0x2eff2201 0x2af2f8c9 0x114b59 0x36156aaf)
libc++abi.dylib: terminating with uncaught exception of type NSException
I have many [NSArray objectAtIndex], I don't know which one makes it crash.
I've writen the debug code below, but still can't catch it. It's in a UITableView, I load more and more cells by pull down the table, then it sometimes crashes.
#import "NSArray+Debug.h"
#import "MLTool.h"
#implementation NSArray (Debug)
- (id)objectAtIndexEx:(NSUInteger)index{
if (self.count<1) {
assert(0);
}
NSString *str=[NSString stringWithFormat:#"count=%d,index=%d,info=%#",self.count,index,[self objectAtIndex:index]];
if ([MLTool isEmptyString:str]
// ||str==
) {
assert(0);
}
NSLogUTF8(#"break:%#",str);
return [self objectAtIndex:index];
}
#end
You can add an "exception breakpoint" in xcode to stop your debugging at the moment of the crash and check why it will crash.
For that in the section breakpoint/debug of the left navigator you can tap on the "+" at the bottom-left corner to add an "Exception breakpoint".
in my application when i run app for first time,it work ok.but when i run again 2 two times, it crashes.
This is the error..
NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 5 beyond bounds for empty array'
Reason: You are accessing Empty array about to access object at index.
replace all places like in your code below
[arrMydata objectAtIndex:indexPath.row];
with
//1. Positive index ([anArray objectAtIndex:-NUMBERS]) will crash
//2. within the array boundary
if([arrMydata count] > 0 && [arrMydata count] > indexPath.row){
shrObj=[arrMydata objectAtIndex:indexPath.row];
}
else{
//Array is empty,handle as you needed
}
**Here You can see the non software example, which will explain this issue. Good luck! **
You array is empty, but you're trying to access an object in it. That is the problem.
Reason: According to your log, you're trying to access empty array. Just fix this by below code
if (arrMydata.count > inxexPath.row)
sharObj = [arrMydata objectAtIndex:indexPath.row]
In case this helps someone : in my case the array was not in code, but an IB outlet that was an array of 5 UIImageViews in the storyboard.
#IBOutlet var upAndDownArrowImages: [UIImageView]!
Reason for the crash was that I mistakenly deleted 1 of those UIImageViews from the Storyboard.
In my case, it Crashes for heightForRowAt indexpath, Do check this method for smooth operation.
Hope it Helps someone.
I have searched for this problem and I know it is caused because an array is manipulated while its enumeration. Earlier in my code, I was using :
-(BOOL)busy
{
for(DataRequest* request in self.active)
if(!request.invisible)
return YES;
return NO;
}
and -(BOOL)busy is being called very frequently as the data loads from the server. Also in my code I have some lines which adds and removes objects in self.active. And because of this I was getting the exception. Then I made a change in the code as:
-(BOOL)busy
{
self.tempActive = self.active;
for(DataRequest* request in _tempActive)
if(!request.invisible)
return YES;
return NO;
}
but I am still getting the same exception. What am I doing wrong, any ideas? This is the only code where self.tempActive is used.
The exception I am getting is:
*** Terminating app due to uncaught exception 'NSGenericException', reason: '*** Collection <__NSArrayM: 0x9ec8f60> was mutated while being enumerated.'
You need to understand the difference between classes and stack objects (like ints and things). Setting something equal to something else does not make a copy of it if it is a class. You need to use [self.active copy] instead.
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];
}