I am using this code for table delegates
my application crashes when I scroll table till last row i.e langTable
if sometime application not crashes then I am not able to scroll the table
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
NSLog(#"Test 0");
if (tableView==langTable) {
NSLog(#"Test 0 complete lang table %d",[langArray count]);
return [langArray count];
}else if (tableView==gameTypeTable) {
NSLog(#"Test 0 complete gametype %d",[gameTypeArray count]);
return [gameTypeArray count];
}
NSLog(#"Test 0 complete 0");
return 0;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithFrame:CGRectZero reuseIdentifier:CellIdentifier] autorelease];
}
// Set up the cell...
NSString *cellValue;
if (tableView==langTable) {
NSLog(#"1Test 1...%d-%#",indexPath.row,[[langArray objectAtIndex:indexPath.row] objectForKey:#"lang_caption"]);
cellValue = [[langArray objectAtIndex:indexPath.row] objectForKey:#"lang_caption"];
}else if (tableView==gameTypeTable) {
NSLog(#"2Test 1...%d-%#",indexPath.row,[[gameTypeArray objectAtIndex:indexPath.row] objectForKey:#"caption"]);
cellValue = [[gameTypeArray objectAtIndex:indexPath.row] objectForKey:#"caption"];
}else {
NSLog(#"3Test 1...%d-kuch.ni.hai",indexPath.row);
cellValue = #"";
}
cell.text = cellValue;
NSLog(#"Text 1 Complete");
return cell;
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath{
NSLog(#"select");
if (tableView==langTable) {
NSLog(#"langTable1");
functionality.gameLang = indexPath.row;
NSLog(#"langTable2");
}else if (tableView==gameTypeTable) {
NSLog(#"gameTypeTable1");
functionality.gameType = indexPath.row;
NSLog(#"gameTypeTable2");
}
}
Log comes on the crash time are
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSMutableArray objectAtIndex:]: index 0 beyond bounds for empty array'
*** Call stack at first throw:
(
0 CoreFoundation 0x026a7919 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x027f55de objc_exception_throw + 47
2 CoreFoundation 0x0269d465 -[__NSArrayM objectAtIndex:] + 261
3 SensoryStimulation 0x00006fe5 -[Functionality onPageChange:] + 829
4 SensoryStimulation 0x000029cc -[SensoryStimulationViewController scrollViewDidEndDecelerating:] + 126
5 UIKit 0x0030b0ad -[UIScrollView(UIScrollViewInternal) _stopScrollDecelerationNotify:] + 322
6 UIKit 0x00315fbb -[UIScrollView(Static) _smoothScroll:] + 3999
7 UIKit 0x003337b8 -[UITableView(_UITableViewPrivate) _smoothScroll:] + 75
8 UIKit 0x00301e88 ScrollerHeartbeatCallback + 129
9 GraphicsServices 0x02e9556d HeartbeatTimerCallback + 35
10 CoreFoundation 0x02688d43 __CFRUNLOOP_IS_CALLING_OUT_TO_A_TIMER_CALLBACK_FUNCTION__ + 19
11 CoreFoundation 0x0268a384 __CFRunLoopDoTimer + 1364
12 CoreFoundation 0x025e6d09 __CFRunLoopRun + 1817
13 CoreFoundation 0x025e6280 CFRunLoopRunSpecific + 208
14 CoreFoundation 0x025e61a1 CFRunLoopRunInMode + 97
15 GraphicsServices 0x02e922c8 GSEventRunModal + 217
16 GraphicsServices 0x02e9238d GSEventRun + 115
17 UIKit 0x002d5b58 UIApplicationMain + 1160
18 SensoryStimulation 0x000027aa main + 84
19 SensoryStimulation 0x0000272a start + 54
)
terminate called after throwing an instance of 'NSException'
Whats wrong with code
Amit Battan
I found the wrong thing
Actually I am also using a UIScrollView in my app, when Table scroll ends then scrollViewDidEndDecelerating method calls which I have use for the UIScrollView.
As UITableView has super class UIScrolView
Amit Battan
Related
In my app , I am returning 10 user objects in batches using NSNotificationCenter. When I get the 10 objects , I want to insert that data in table view. For this I am using following code
- (void)viewDidAppear:(BOOL)animated {
recordCounter = 0;
noOfRowsCounter = 0;
// Some code
}
- (void) gotNotification: (NSNotification *) notification {
NSMutableArray *tempArray = [[notification userInfo]valueForKey:KEY];
NSLog(#"recordCounter BEFORE=> %d",recordCounter);
NSLog(#"noOfRowsCounter BEFORE=> %d",noOfRowsCounter);
self.insertIndexPaths = [[NSMutableArray alloc] init];
for (User *user in tempArray)
{
[self.contactsArray addObject:user];
recordCounter++;
}
for (noOfRowsCounter = noOfRowsCounter; noOfRowsCounter < recordCounter; noOfRowsCounter++) {
[self.insertIndexPaths addObject:[NSIndexPath indexPathForRow:recordCounter inSection:0]];
}
NSLog(#"recordCounter AFTER=> %d",recordCounter);
NSLog(#"noOfRowsCounter AFTER=> %d",noOfRowsCounter);
NSLog(#"self.insertIndexPaths count=> %d",[self.insertIndexPaths count]);
[contactsTableView beginUpdates];
[contactsTableView insertRowsAtIndexPaths:self.insertIndexPaths
withRowAnimation:UITableViewRowAnimationNone];
[contactsTableView endUpdates];
[self.insertIndexPaths removeAllObjects];
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// I am doing this as I have 2 records in single row
if ([self.insertIndexPaths count]%2 == 0) {
NSLog(#"In IF::rows:: %d",[self.insertIndexPaths count]/2);
return [self.insertIndexPaths count]/2;
}
else {
NSLog(#"In ELSE::rows:: %d",[self.insertIndexPaths count]/2+1);
return [self.insertIndexPaths count]/2 + 1;
}
}
If I run my app I get the following errors & my app crashed. Here is my console log
2012-04-04 12:15:36.559 AppName[1742:6803] recordCounter BEFORE=> 0
2012-04-04 12:15:36.563 AppName[1742:6803] noOfRowsCounter BEFORE=> 0
2012-04-04 12:15:38.539 AppName[1742:6803] recordCounter AFTER=> 10
2012-04-04 12:15:38.543 AppName[1742:6803] noOfRowsCounter AFTER=> 10
2012-04-04 12:15:38.546 AppName[1742:6803] self.insertIndexPaths count=> 10
2012-04-04 12:15:42.971 AppName[1742:6803] In IF::rows:: 5
2012-04-04 12:15:44.292 AppName[1742:6803] *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit/UIKit-1448.89/UITableView.m:995
2012-04-04 12:15:44.306 AppName[1742:6803] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of rows in section 0. The number of rows contained in an existing section after the update (5) must be equal to the number of rows contained in that section before the update (0), plus or minus the number of rows inserted or deleted from that section (10 inserted, 0 deleted).'
*** Call stack at first throw:
(
0 CoreFoundation 0x36c4164f __exceptionPreprocess + 114
1 libobjc.A.dylib 0x332fec5d objc_exception_throw + 24
2 CoreFoundation 0x36c41491 +[NSException raise:format:arguments:] + 68
3 Foundation 0x334ec573 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 62
4 UIKit 0x30ca4379 -[UITableView(_UITableViewPrivate) _endCellAnimationsWithContext:] + 4500
5 UIKit 0x30cae2f9 -[UITableView endUpdatesWithContext:] + 28
6 UIKit 0x30cae2d5 -[UITableView endUpdates] + 16
7 AppName 0x00004927 -[AppNameViewController batchNotification:] + 770
8 Foundation 0x334a4183 _nsnote_callback + 142
9 CoreFoundation 0x36c1020f __CFXNotificationPost_old + 402
10 CoreFoundation 0x36baaeeb _CFXNotificationPostNotification + 118
11 Foundation 0x334a15d3 -[NSNotificationCenter postNotificationName:object:userInfo:] + 70
12 AppName 0x00007705 -[AddressBook getAddressBookData] + 1700
13 AppName 0x0000447b -[AppNameViewController retriveAddressBookData] + 102
14 Foundation 0x334b3389 -[NSThread main] + 44
15 Foundation 0x335255cd __NSThread__main__ + 972
16 libsystem_c.dylib 0x350c0311 _pthread_start + 248
17 libsystem_c.dylib 0x350c1bbc start_wqthread + 0
)
terminate called after throwing an instance of 'NSException'
I want to add those records in table view . How can I do this. Thanks
UPDATE : Code of cellForRowAtIndexPath
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
ContactCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil)
{
NSArray *cellArray=[[NSBundle mainBundle] loadNibNamed:#"ContactCell" owner:self options:nil];
//NSLog(#"cellArray count => %d",[cellArray count]);
cell=[cellArray objectAtIndex:0];
}
// Configure the cell...
// For showing 2 records in single row
int row = indexPath.row * 2;
if (row <= [self.contactsArray count])
{
User *user = [self.contactsArray objectAtIndex:row];
NSLog(#"In ROW: %#",user.firstName);
cell.firstNameLabel.text=[NSString stringWithFormat:#"%#",nameString];
}
if ((row + 1) < [self.contactsArray count])
{
User *user = [self.contactsArray objectAtIndex:row+1];
NSLog(#"In ROW+1: %#",user.firstName);
cell.secondNameLabel.text=[NSString stringWithFormat:#"%#",nameString];
}
return cell;
}
according to your data you are returning 5 in number of rows in section but your
self.insertIndexPaths is having 10 index paths
[contactsTableView insertRowsAtIndexPaths:self.insertIndexPaths
withRowAnimation:UITableViewRowAnimationNone];
these lines specify to insert 10 rows,as mentioned clearly in the error in number of rows you get after updates should equal to the value returned in number of rows in section.
replace the lines
for (noOfRowsCounter = noOfRowsCounter; noOfRowsCounter < recordCounter; noOfRowsCounter++) {
[self.insertIndexPaths addObject:[NSIndexPath indexPathForRow:recordCounter inSection:0]];
}
with
int presentrows = [yourtablename numberOfRowsInSection:0];
int Finalnumberofrows;
if ([self.insertIndexPaths count]%2 == 0) {
Finalnumberofrows = [self.contactsArray count]/2;
}
else {
Finalnumberofrows = [self.contactsArray count]/2 + 1;
}
for (presentrows; presentrows < Finalnumberofrows; presentrows++) {
[self.insertIndexPaths addObject:[NSIndexPath indexPathForRow:presentrows inSection:0]];
}
and replace
table view cell for row at index method
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
// I am doing this as I have 2 records in single row
if ([self.contactsArray count]%2 == 0) {
NSLog(#"In IF::rows:: %d",[self.insertIndexPaths count]/2);
return [self.contactsArray count]/2;
}
else {
NSLog(#"In ELSE::rows:: %d",[self.insertIndexPaths count]/2+1);
return [self.contactsArray count]/2 + 1;
}
}
The real error is listed after Terminating app due to uncaught exception.
It says: invalid number of rows in section 0. The number of rows contained in an existing section after the update (5) must be equal to the number of rows contained in that section before the update (0), plus or minus the number of rows inserted or deleted from that section (10 inserted, 0 deleted)
So, what's the problem? You had 0 rows, then inserted 10 and now say it has 5 ones? Doesn't make any sense. You should check your -tableView:numberOfRowsInSection: implementation.
I just see that you want to display two records in a single row. That makes no sense, really. It makes that table view animation just unnecessarily complicated.
However, if you'd want to stick with that you may not tell the table that you inserted 10 but 5 rows.
I define my array in my AppDelegate.h like this:
NSMutableArray *myWishesArray;
.
.
#property (nonatomic, retain) NSMutableArray *myWishesArray;
In AppDelegate.m, i allocate its object like this:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
myWishesArray = [[NSMutableArray alloc] init];
.
.
return YES;
}
Suppose i have a function "Add Data to array", like this:
-(void)addDataToArray
{
NSMutableArray *tempArray = //Gets data from a web service
if ([tempArray count] > 0) {
[objAppDelegate.myWishesArray addObjectsFromArray:tempArray];
[self.myWishesTableView reloadData];
}
}
In viewDidLoad of MyViewController.m, I load the first set of 8 records into my array:
- (void)viewDidLoad {
[self addDataToArray]; //fetches page number 1 of the data to be fetched
}
In scrollViewDidEndDragging of MyViewController.m, i add next set of 8 records and use the same above mentioned code to add it in the objAppDelegate.myWishesArray:
-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
currentPageNumber++;
[self addDataToArray]; //fetches data for next page number
}
-(void)viewWillAppear:(BOOL)animated
{
[self.myWishesTableView reloadData];
}
This is my cellForRowAtIndexPath method:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
MyObject *myArrayObject = [objAppDelegate.myWishesArray objectAtIndex:indexPath.row];
}
Every time i try to click a row of the table which was visible in my table view, but was just at the end of being loaded, my app gets crashed with the following exception. It may be initial loading or loading more rows as a result of scrolling down the table view. Please keep in mind that when i give the table view enough time to settle and the motion stops and data is fully loaded, then i dont face any exception on clicking the loaded rows.
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSArray objectAtIndex:]: index 0 beyond bounds for empty array'
*** Call stack at first throw:
(
0 CoreFoundation 0x013a8be9 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x014fd5c2 objc_exception_throw + 47
2 CoreFoundation 0x0139e80c -[__NSArrayI objectAtIndex:] + 236
3 WishHaHa 0x00004e1a -[AsyncImageView image] + 66
4 UIKit 0x0044e56b -[UIImageView setBackgroundColor:] + 101
5 UIKit 0x00549448 -[UITableViewCell _setOpaque:forSubview:] + 953
6 UIKit 0x0054951c -[UITableViewCell _setOpaque:forSubview:] + 1165
7 UIKit 0x0054951c -[UITableViewCell _setOpaque:forSubview:] + 1165
8 UIKit 0x0054472d -[UITableViewCell(UITableViewCellStatic) _updateAndCacheBackgroundColorForHighlightIgnoringSelection:] + 117
9 UIKit 0x0054c12a -[UITableViewCell showSelectedBackgroundView:animated:] + 1435
10 UIKit 0x00548ce3 -[UITableViewCell setHighlighted:animated:] + 231
11 UIKit 0x003fbd3b -[UITableView highlightRowAtIndexPath:animated:scrollPosition:] + 756
12 UIKit 0x003f78d8 -[UITableView touchesBegan:withEvent:] + 1349
13 UIKit 0x004512b8 forwardMethod2 + 92
14 UIKit 0x0054cc15 -[UITableViewCell touchesBegan:withEvent:] + 319
15 UIKit 0x004512b8 forwardMethod2 + 92
16 UIKit 0x00610987 _UIGestureRecognizerSortAndSendDelayedTouches + 3609
17 UIKit 0x006110fc _UIGestureRecognizerUpdateObserver + 927
18 CoreFoundation 0x01389fbb __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 27
19 CoreFoundation 0x0131f0e7 __CFRunLoopDoObservers + 295
20 CoreFoundation 0x012e7bd7 __CFRunLoopRun + 1575
21 CoreFoundation 0x012e7240 CFRunLoopRunSpecific + 208
22 CoreFoundation 0x012e7161 CFRunLoopRunInMode + 97
23 GraphicsServices 0x01a9d268 GSEventRunModal + 217
24 GraphicsServices 0x01a9d32d GSEventRun + 115
25 UIKit 0x0039442e UIApplicationMain + 1160
26 WishHaHa 0x00002a5c main + 102
27 WishHaHa 0x000029ed start + 53
)
terminate called after throwing an instance of 'NSException'
I have done a lot of research on my problem and found that possible causes of NSRangeException may be:
numberOfRowsInSection:(NSInteger)section; method of the UITableView's
data source is delivering wrong values.
retain should be called on the array.
Whenever you modify the underlying data for a table view you need to
update the changes by either calling -[UITableView reloadData]; or
the beginUpdates and endUpdates methods then adding or removing the
correct index paths.
I dont think that my code has first issue. If there is second issue, then where should i make the call to retain myWishesArray? If there is third issue with my code, then how should i proceed to change my code?
Please let me know where i am doing anything wrong. I am stuck on this issue since really long.
Thanks
Edit:
After thorough investigation of the code, i have found the point which is causing this error. I am asynchronously downloading the images in cells of my table view, using the asyncimageview class. Let me paste some code here:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"CustomWishCell";
CustomWishCell *cell = (CustomWishCell *) [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:#"CustomWishCell" owner:self options:nil];
for (id currentObject in topLevelObjects){
if ([currentObject isKindOfClass:[UITableViewCell class]]){
cell = (CustomWishCell *) currentObject;
break;
}
}
}
else
{
AsyncImageView* oldImage = (AsyncImageView*)[cell.contentView viewWithTag:999];
[oldImage removeFromSuperview];
}
if (indexPath.row<[objAppDelegate.myWishesArray count]) {
Wish *objWish = [objAppDelegate.myWishesArray objectAtIndex:indexPath.row];
NSString *test = objWish.facebookUserId;
[self.myEngine loadAsynchronousPhotoAvatarInView:objWish.facebookUserId imageView:cell.contentView];
cell.wishLabel.attributedText = [self.myEngine makeWisherNameAndContents:objWish.firstName lastName:objWish.lastName wishContents:objWish.contents];
}
return cell;
}
Now, myEngine contains the definitioin:
-(void)loadAsynchronousImageURLInView:(NSString*)imageUrl imageView:(UIView*)targetView
{
CGRect frame;
frame.size.width=45;
frame.size.height=45;
frame.origin.x=0;
frame.origin.y=0;
if (imageUrl != (id)[NSNull null] )
{
AsyncImageView* asyncImage = [[[AsyncImageView alloc]initWithFrame:frame] autorelease];
asyncImage.tag = 999;
NSURL *url = [NSURL URLWithString:imageUrl];
[asyncImage loadImageFromURL:url];
[targetView addSubview:asyncImage];
}
}
And the AsyncImageView class loads the image using NSURLConnection class.
Please note that the app works all ok when i comment this line defined in cellForRowAtIndexPath method:
[self.myEngine loadAsynchronousPhotoAvatarInView:objWish.facebookUserId imageView:cell.contentView];
It does not crash when i click on any row that was loading. Please let me know how should i change my logic. I am not allowed to load the images synchronously, or show any indicator while images are downloading.
Your array with which you are loading your tableview is either not getting filled or is getting released somewhere before you tap on the tableView.
Please add the code where you release your array and Also please make sure that you are synthesizing your array in AppDelegate.
I think there is some issue with the array and not the tableView as array is getting empty.
I hope this helps.
It sounds to me as if your addDataToArray method does not manage to retrieve the data and fill the myWishesArray array before the click is handled.
Are you retrieving the data from the web service asynchronously?
Is there any way to retrieve all the data at once instead of retrieving it by sections?
- (void)viewDidLoad {
[super viewDidLoad];
NSOperationQueue *queue = [NSOperationQueue new];
NSInvocationOperation *operation = [[NSInvocationOperation alloc]
initWithTarget:self selector:#selector(loadImage) object:nil];
[queue addOperation:operation];
[operation release];
NSMutableArray *_array = [[NSMutableArray alloc] initWithCapacity:10000];
self.array = _array;
[_array release];
}
- (void)loadImage
{
for(int i = 0;i < [appDelegate.ArrParseData count]; i++ )
{
NSLog(#" count %i",i);
// Configure the cell...
XMLTags *xmltag = [appDelegate.ArrParseData objectAtIndex:i];
NSString *Img_id, *Img_name, *DynamicImgUrl;
Img_id = xmltag.equip_id;
Img_name = xmltag.image;
DynamicImgUrl = [NSString stringWithFormat:#"http://testetete.com/pics/equipment/%#/%#",Img_id, Img_name];
NSURL *ImageUrl = [NSURL URLWithString:DynamicImgUrl];
NSLog(#" ccxvount %#",ImageUrl);
UIImage *image = [UIImage imageWithData: [NSData dataWithContentsOfURL:ImageUrl]];
NSLog(#" ccxvount %i",i);
[self.array addObject:image];
NSLog(#" ccxvount %i",i);
}
[self.tableView performSelectorOnMainThread:#selector(reloadData) withObject:nil waitUntilDone:YES];
}
// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
UIImageView *top_img = [[UIImageView alloc] initWithFrame:CGRectMake(10, 25, 75, 80)];
CGRect rect = top_img.frame;
rect.size.height = 60;
rect.size.width = 60;
top_img.frame = rect;
// the imageView holds the image myImg
top_img.image = [self.array objectAtIndex:indexPath.row];
//cell.imageView.image=image;
[cell.contentView addSubview:top_img];
return cell;
}
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
// Return the number of sections.
return 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return [appDelegate.ArrParseData count];
}
when i excecute the above code my application gets crashes with the following error..
Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[NSMutableArray objectAtIndex:]: index 0 beyond bounds for empty array'
*** Call stack at first throw:
(
0 CoreFoundation 0x026cc919 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x0281a5de objc_exception_throw + 47
2 CoreFoundation 0x026c2465 -[__NSArrayM objectAtIndex:] + 261
3 AgSearch 0x00006f80 -[EquipmentViewController tableView:cellForRowAtIndexPath:] + 752
4 UIKit 0x00345a3f -[UITableView(UITableViewInternal) _createPreparedCellForGlobalRow:withIndexPath:] + 619
5 UIKit 0x0033bad2 -[UITableView(UITableViewInternal) _createPreparedCellForGlobalRow:] + 75
6 UIKit 0x0035040c -[UITableView(_UITableViewPrivate) _updateVisibleCellsNow:] + 1561
7 UIKit 0x003484bc -[UITableView layoutSubviews] + 242
8 QuartzCore 0x024620d5 -[CALayer layoutSublayers] + 177
9 QuartzCore 0x02461e05 CALayerLayoutIfNeeded + 220
10 QuartzCore 0x0246164c _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 302
11 QuartzCore 0x024612b0 _ZN2CA11Transaction6commitEv + 292
12 QuartzCore 0x02468f5b _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 99
13 CoreFoundation 0x026add1b __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 27
14 CoreFoundation 0x02642987 __CFRunLoopDoObservers + 295
15 CoreFoundation 0x0260bc17 __CFRunLoopRun + 1575
16 CoreFoundation 0x0260b280 CFRunLoopRunSpecific + 208
17 CoreFoundation 0x0260b1a1 CFRunLoopRunInMode + 97
18 GraphicsServices 0x02f312c8 GSEventRunModal + 217
19 GraphicsServices 0x02f3138d GSEventRun + 115
20 UIKit 0x002e3b58 UIApplicationMain + 1160
21 AgSearch 0x0000206c main + 102
22 AgSearch 0x00001ffd start + 53
23 ??? 0x00000001 0x0 + 1
)
terminate called after throwing an instance of 'NSException'
Any help would be greatly appreciated....
Thanks for nay help
does the array has any data when you show the table? if you give a default number of cells that is bigger than 0 and there is no data in the array..then you will receive the error you described.
'NSRangeException', reason: '*** -[NSMutableArray objectAtIndex:]: index 0 beyond bounds for empty array'
EDIT:
in
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
// Return the number of rows in the section.
return [appDelegate.ArrParseData count];
}
you shouldn't return the number of elements from the appDelegate.ArrParseData because if that array is filled with data then you will receive a number X bigger than 0.
in the cellForRowAtIndexPath you ask for information at index X but self.array is not filled yet with data because you call the loadImage method async.
You should return [self.array count]; in the numberOfRowsInSection method.
I don't think you are showing all the code you need to show - the trace shows the exception happens some time in cellForRowAtIndexPath. Looks like you are accessing an array that contains nothing - are you completely sure the array has been loaded by the time you try to use it?
Likely you know how many cells there will be and you report that correctly through numberOfRowsInSection, but you haven't populated the array by the time it is required. You need to so something like display placeholders until the load is finished, leave the images nil (empty) until ready, make the data load/view appearance sequential, get the load happening in the background earlier or something like that.
Your number of rows method is accessing a different count array from the one which contains your image, isn't it?
If you executed this code in no concurrent way, you wouldn't have this error. The problem comes when the thread who has to fill in your images array is slower than the main one.
So your best solution would be to check the images array size before accessing it and if you want you could send a reloadRowsAtIndexPaths: withRowAnimation: message to your tableView every time that you get a new image. This would give you a nice loading effect.
I hope I've been clear enough.
See you!
maybe someone make such stupid mistake like me in:
- (void)configureCell:(UITableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
and try to do something like this:SomeObject = [SomeContainer objectAtIndex:indexPath]; Or even try to be clever with cast: SomeObject = [SomeContainer objectAtIndex:(int)indexPath]; WRONG
no way...JUST
remember to get index you have to call indexPath.row!!!!!
So, I'm debugging an app I'm building and using the description method to help me find the problem. But instead of giving me the app as a string it is printing out parentheses instead. Please help!
Here's the code:
- (void)viewDidLoad {
[super viewDidLoad];
reminders = [[NSMutableArray alloc] init];
currentTitle = [[NSMutableString alloc] init];
currentDate = [[NSMutableString alloc] init];
currentSummary = [[
NSMutableString alloc] init];
currentLink = [[NSMutableString alloc] init];
NSLog(#"IT'S HERE %#", [reminders description]);}
...
and the error:
[Session started at 2010-10-04 22:15:16 -0400.]
2010-10-04 22:15:17.434 Reminders[5824:207] ******* Accessibility Status Changed: On
2010-10-04 22:15:17.464 Reminders[5824:207] ********** Loading AX for: com.yourcompany.Reminders ************
2010-10-04 22:15:17.506 Reminders[5824:207] IT'S HERE (
)
2010-10-04 22:15:17.510 Reminders[5824:207] Hello
2010-10-04 22:15:17.512 Reminders[5824:207] (
)
2010-10-04 22:15:17.514 Reminders[5824:207] PVC: <UITableView: 0x602d600; frame = (0 20; 320 460); clipsToBounds = YES; opaque = NO; autoresize = W+H; layer = <CALayer: 0x5f3f3b0>; contentOffset: {0, 0}>
2010-10-04 22:15:17.514 Reminders[5824:207] It's here
2010-10-04 22:15:17.515 Reminders[5824:207] Loaded
2010-10-04 22:15:17.520 Reminders[5824:207] -[__NSCFArray name]: unrecognized selector sent to instance 0x6a4b640
2010-10-04 22:15:17.523 Reminders[5824:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFArray name]: unrecognized selector sent to instance 0x6a4b640'
*** Call stack at first throw:
(
0 CoreFoundation 0x0248bb99 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x025db40e objc_exception_throw + 47
2 CoreFoundation 0x0248d6ab -[NSObject(NSObject) doesNotRecognizeSelector:] + 187
3 CoreFoundation 0x023fd2b6 ___forwarding___ + 966
4 CoreFoundation 0x023fce72 _CF_forwarding_prep_0 + 50
5 Reminders 0x00003aa9 -[RootViewController tableView:cellForRowAtIndexPath:] + 300
6 UIKit 0x00090d6f -[UITableView(UITableViewInternal) _createPreparedCellForGlobalRow:withIndexPath:] + 619
7 UIKit 0x00086e02 -[UITableView(UITableViewInternal) _createPreparedCellForGlobalRow:] + 75
8 UIKit 0x0009b774 -[UITableView(_UITableViewPrivate) _updateVisibleCellsNow:] + 1561
9 UIKit 0x000937ec -[UITableView layoutSubviews] + 242
10 QuartzCore 0x03f60481 -[CALayer layoutSublayers] + 177
11 QuartzCore 0x03f601b1 CALayerLayoutIfNeeded + 220
12 QuartzCore 0x03f592e0 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 302
13 QuartzCore 0x03f59040 _ZN2CA11Transaction6commitEv + 292
14 UIKit 0x0002204e -[UIApplication _reportAppLaunchFinished] + 39
15 UIKit 0x00022477 -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 545
16 UIKit 0x0002c3ec -[UIApplication handleEvent:withNewEvent:] + 1958
17 UIKit 0x00024b3c -[UIApplication sendEvent:] + 71
18 UIKit 0x000299bf _UIApplicationHandleEvent + 7672
19 GraphicsServices 0x026fa822 PurpleEventCallback + 1550
20 CoreFoundation 0x0246cff4 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
21 CoreFoundation 0x023cd807 __CFRunLoopDoSource1 + 215
22 CoreFoundation 0x023caa93 __CFRunLoopRun + 979
23 CoreFoundation 0x023ca350 CFRunLoopRunSpecific + 208
24 CoreFoundation 0x023ca271 CFRunLoopRunInMode + 97
25 UIKit 0x00021c6d -[UIApplication _run] + 625
26 UIKit 0x0002daf2 UIApplicationMain + 1160
27 Reminders 0x00002078 main + 102
28 Reminders 0x00002009 start + 53
)
terminate called after throwing an instance of 'NSException'
Here's the method that you asked for fluchtpunkt
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"cell";
cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell.
Reminder *theReminder = [reminders objectAtIndex:indexPath.row];
cell.textLabel.text = theReminder.name;
return cell;
}
those parentheses are the output I would expect if I NSLog an empty array.
This is absolutely correct.
the exception is raised because you try to call a name method on an NS(Mutable)Array. And arrays don't respond to name.
To find the cause of this Exception post the code of this method in your RootViewController
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
I've got a UITableViewController with a bunch of random items in it. I want to be able to add items to it, and delete items from it. I have a UITextField in the first section header, so you can type in a word/phrase and add it to the list.
You can delete words from the list without issue, however, if you add a word to the list, then try to delete it, the app ends and returns to the home screen; nothing appears in the console.
I'm not sure where the problem lies. Here's the addNewWord method I've been using:
- (void)addNewWord
{
NSString *newWord = [textField text];
[array insertObject:newWord atIndex:0];
NSLog(#"%d", [array count]);
[textField setText:#""];
[[self tableView] reloadData];
}
And here is the -(void) tableView:commitEditingStyle:forRowAtIndexPath method
- (void)tableView:(UITableView *)tableView
commitEditingStyle:(UITableViewCellEditingStyle)editingStyle
forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (editingStyle == UITableViewCellEditingStyleDelete) {
[array removeObjectAtIndex:[indexPath row]];
[tableView beginUpdates];
[tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath]
withRowAnimation:UITableViewRowAnimationRight];
[tableView endUpdates];
}
NSLog(#"%d", [array count]);
}
That's all I've come up with as to where the problem might be, which is also why I'm stuck.
Any insight is greatly appreciated. Thank you very much!
-Edit: Added [tableView beginUpdates]; and [tableView endUpdates]; same results. Any other ideas?
-Edit2: When I added the [tableView beginUpdates]; and [tableView endUpdates];, I get an exception. Here's the console output:
2010-09-30 05:56:40.172 DictionaryWordsTest[2350:207] *** Assertion failure in
-[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/
UIKit-1262.60.3/UITableView.m:920
2010-09-30 05:56:40.175 DictionaryWordsTest[2350:207] *** Terminating app
due to uncaught exception 'NSInternalInconsistencyException', reason:
'Invalid update: invalid number of rows in section 0. The number of rows
contained in an existing section after the update (17) must be equal to the
number of rows contained in that section before the update (17),
plus or minus the number of rows inserted or deleted from that section
(0 inserted, 1 deleted).'
*** Call stack at first throw:
(
0 CoreFoundation 0x02486b99 __exceptionPreprocess + 185
1 libobjc.A.dylib 0x025d640e objc_exception_throw + 47
2 CoreFoundation 0x0243f238 +[NSException raise:format:arguments:] + 136
3 Foundation 0x000b2e37 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 116
4 UIKit 0x00332d37 -[UITableView(_UITableViewPrivate) _endCellAnimationsWithContext:] + 8719
5 UIKit 0x00322a01 -[UITableView endUpdates] + 42
6 DictionaryWordsTest 0x00002a73 -[DictionaryViewController tableView:commitEditingStyle:forRowAtIndexPath:] + 140
7 UIKit 0x0031f96d -[UITableView(UITableViewInternal) animateDeletionOfRowWithCell:] + 101
8 UIKit 0x002b87f8 -[UIApplication sendAction:to:from:forEvent:] + 119
9 UIKit 0x00343de0 -[UIControl sendAction:to:forEvent:] + 67
10 UIKit 0x00346262 -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 527
11 UIKit 0x00344e0f -[UIControl touchesEnded:withEvent:] + 458
12 UIKit 0x002dc3d0 -[UIWindow _sendTouchesForEvent:] + 567
13 UIKit 0x002bdcb4 -[UIApplication sendEvent:] + 447
14 UIKit 0x002c29bf _UIApplicationHandleEvent + 7672
15 GraphicsServices 0x02d66822 PurpleEventCallback + 1550
16 CoreFoundation 0x02467ff4 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 52
17 CoreFoundation 0x023c8807 __CFRunLoopDoSource1 + 215
18 CoreFoundation 0x023c5a93 __CFRunLoopRun + 979
19 CoreFoundation 0x023c5350 CFRunLoopRunSpecific + 208
20 CoreFoundation 0x023c5271 CFRunLoopRunInMode + 97
21 GraphicsServices 0x02d6500c GSEventRunModal + 217
22 GraphicsServices 0x02d650d1 GSEventRun + 115
23 UIKit 0x002c6af2 UIApplicationMain + 1160
24 DictionaryWordsTest 0x00001f58 main + 102
25 DictionaryWordsTest 0x00001ee9 start + 53
)
terminate called after throwing an instance of 'NSException'
You need to wrap your -[tableView deleteRowsAtIndexPaths] call with [tableView beginUpdates] and [tableView endUpdates].
Oddly enough, the answer ended up being something other than what I had expected. I'm not sure what the difference is, and why I was getting no console output, but here's what I ended up doing.
In addNewWord, instead of using reloadData, I used these methods to reload the tableView, and insert the word at the top (So I didn't have to scroll to the bottom of the view to see the new word):
- (void)addNewWord
{
[[self tableView] beginUpdates];
NSString *newWord = [textField text];
[array insertObject:newWord atIndex:0];
[textField setText:#""];
NSIndexPath *indexPath = [NSIndexPath indexPathForRow:0 inSection:0];
[self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationLeft];
[[self tableView] endUpdates];
}
Then, I think the key is, that addNewWord isn't called from:
[textField addTarget:self action:#selector(addNewWord) forControlEvents:UIControlEventEditingDidEndOnExit];
But, I added a button next to my textfield that calls it. Everything works now.