Under what circumstances do UITableView give -1 or NSUIntegerMax for the row in -[UITableViewDelegate tableView:titleForDeleteConfirmationButtonForRowAtIndexPath:]?
Below it is a crash log form an user.
OS Version: iPhone OS 9.2.1 (13D15)
Application Specific Information:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'no object at index 18446744073709551615 in section at index 0'
Last Exception Backtrace:
0 CoreFoundation 0x0000000181241900 __exceptionPreprocess + 124
1 libobjc.A.dylib 0x00000001808aff80 objc_exception_throw + 56
2 CoreData 0x0000000182cc50bc -[NSFetchedResultsController objectAtIndexPath:] + 456
3 My App 0x000000010022c678 -[MyViewController tableView:titleForDeleteConfirmationButtonForRowAtIndexPath:] (MyViewController.m:560)
4 UIKit 0x0000000186145174 -[UITableView _titleForDeleteConfirmationButtonForRowAtIndexPath:] + 160
5 UIKit 0x00000001862756f4 -[UITableView _deleteConfirmationButtonForRowAtIndexPath:] + 116
6 UIKit 0x0000000186275cf4 -[UITableView _swipeActionButtonsForRowAtIndexPath:] + 824
7 UIKit 0x0000000186275998 -[UITableView _swipeActionButtons] + 92
8 UIKit 0x0000000186144bd8 __32-[UITableViewCell _beginSwiping]_block_invoke + 120
9 UIKit 0x0000000185f42964 +[UIView(Animation) performWithoutAnimation:] + 80
10 UIKit 0x0000000186144b48 -[UITableViewCell _beginSwiping] + 96
11 UIKit 0x0000000186272320 -[UITableViewWrapperView handleSwipeBeginning:] + 256
12 UIKit 0x00000001864b4ea4 _UIGestureRecognizerSendTargetActions + 396
13 UIKit 0x00000001860d85b8 _UIGestureRecognizerSendActions + 172
14 UIKit 0x0000000185f669b0 -[UIGestureRecognizer _updateGestureWithEvent:buttonEvent:] + 784
15 UIKit 0x00000001864b63bc ___UIGestureRecognizerUpdate_block_invoke904 + 72
16 UIKit 0x0000000185f25b58 _UIGestureRecognizerRemoveObjectsFromArrayAndApplyBlocks + 372
17 UIKit 0x0000000185f228dc _UIGestureRecognizerUpdate + 2404
18 UIKit 0x0000000185f64820 -[UIWindow _sendGesturesForEvent:] + 1132
19 UIKit 0x0000000185f63e1c -[UIWindow sendEvent:] + 764
20 UIKit 0x0000000185f344cc -[UIApplication sendEvent:] + 248
21 UIKit 0x0000000185f32794 _UIApplicationHandleEventQueue + 5528
22 CoreFoundation 0x00000001811f8efc __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
23 CoreFoundation 0x00000001811f8990 __CFRunLoopDoSources0 + 540
24 CoreFoundation 0x00000001811f6690 __CFRunLoopRun + 724
25 CoreFoundation 0x0000000181125680 CFRunLoopRunSpecific + 384
26 GraphicsServices 0x0000000182634088 GSEventRunModal + 180
27 UIKit 0x0000000185f9cd90 UIApplicationMain + 204
28 My App 0x00000001000a926c main (main.m:16)
29 ??? 0x0000000180cc68b8 0x0 + 0
- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath
{
MyMessage *message = [self messageAtIndex:indexPath.row];
if ([message.senderUid isEqualToString:mUid])
return NSLocalizedString(#"Delete", nil);
else
return NSLocalizedString(#"Hide", nil);
}
- (MyMessage *)messageAtIndex:(NSInteger)index
{
return [mMessagesController objectAtIndexPath:[NSIndexPath indexPathForRow:index inSection:0]];
}
indexPath.row and indexPath.section are each a NSUInteger (unsigned integer), which means that it's strictly positive. If you subtract and end up going negative, it jumps up to NSUIntegerMax. This makes it necessary to be careful with arithmetic involving index paths.
When you do row - 1 for row equal to zero, you will get NSUIntegerMax.
I guess the answer is: under no circumstance. If you're cell would be out of bounds the crash would display on rendering time, not when accessing [UITableViewDelegate tableView:titleForDeleteConfirmationButtonForRowAtIndexPath:]
So the issue has to do with trying to retrieve an object from mMessagesController. Try using:
- (MyMessage *)messageAtIndex:(NSInteger)index
{
return [[mMessagesController fetchedObjects] objectAtIndexPath:[NSIndexPath indexPathForRow:index inSection:0]];
}
or
- (MyMessage *)messageAtIndex:(NSInteger)index
{
return [mMessagesController objectAtIndex:index];
}
In Addition you could also filter the call to messageAtIndex to avoid going out of bounds.
- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.row < [mMessagesController fetchedObjects].count && indexPath.row >= 0) {
MyMessage *message = [self messageAtIndex:indexPath.row];
if ([message.senderUid isEqualToString:mUid])
return NSLocalizedString(#"Delete", nil);
else
return NSLocalizedString(#"Hide", nil);
} else {
return NSLocalizedString(#"Error", nil);
}
}
It is an iOS bug. Apple marked my bug as a duplicate of 23821434.
Related
Application Specific Information:
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -'[__NSArrayM objectAtIndex:]: index 5 beyond bounds [0 .. 3]'
0 CoreFoundation __exceptionPreprocess + 124
1 libobjc.A.dylib objc_exception_throw + 56
2 CoreFoundation -[__NSArrayM removeObjectAtIndex:] + 0
3 UIKit -[UITableView cellForRowAtIndexPath:] + 252
4 someApp -[businessViewClass methodA:] (businessViewClass.m:298)
5 someApp -[businessViewClass scrollViewDidScroll:] (businessViewClass.m:292)
6 UIKit -[UIScrollView(UIScrollViewInternal) _notifyDidScroll] + 76
7 UIKit -[UIScrollView setContentOffset:] + 460
8 UIKit -[UITableView setContentOffset:] + 300
9 UIKit -[UIScrollView(UIScrollViewInternal) _adjustContentOffsetIfNecessary] + 60
10 UIKit -[UIScrollView setContentSize:] + 128
11 UIKit -[UITableView _applyContentSizeDeltaForEstimatedHeightAdjustments:] + 56
12 UIKit -[UITableViewRowData setHeight:forRowAtIndexPath:] + 572
13 UIKit __53-[UITableView _configureCellForDisplay:forIndexPath:]_block_invoke + 3016
14 UIKit +[UIView(Animation) performWithoutAnimation:] + 80
15 UIKit -[UITableView _configureCellForDisplay:forIndexPath:] + 460
16 UIKit -[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 788
17 UIKit -[UITableView _createPreparedCellForGlobalRow:willDisplay:] + 80
18 UIKit -[UITableView _updateVisibleCellsNow:isRecursive:] + 2360
19 UIKit -[UITableView cellForRowAtIndexPath:] + 136
20 someApp -[businessViewClass methodA:] (businessViewClass.m:298)
21 UIKit -[UIScrollView(UIScrollViewInternal) _notifyDidScroll] + 76
22 UIKit -[UIScrollView setContentOffset:] + 460
23 UIKit -[UITableView setContentOffset:] + 300
24 UIKit -[UIScrollView _smoothScrollWithUpdateTime:] + 2400
25 QuartzCore CA::Display::DisplayLinkItem::dispatch() + 40
26 QuartzCore CA::Display::DisplayLink::dispatch_items(unsigned long long, unsigned long long, unsigned long long) + 424
27 IOKit 0x000000018334de54 0x183348000 + 24148
28 CoreFoundation __CFMachPortPerform + 180
29 CoreFoundation __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 56
30 CoreFoundation __CFRunLoopDoSource1 + 436
31 CoreFoundation __CFRunLoopRun + 1800
32 CoreFoundation CFRunLoopRunSpecific + 384
33 GraphicsServices GSEventRunModal + 180
34 UIKit UIApplicationMain + 204
35 someApp main (main.m:15)
36 libdyld.dylib 0x0000000182b528b8 0x182b50000 + 10424
This is what happend.
I find an bug that exists in app online, but I can't reproduce it with project code. It seems a business method was called when scroll the UIScrollview, and this business method call cellForRowAtIndexPath method of UITableView, and then cellForRowAtIndexPath trigs the scrollViewDidScroll method of UIScrollView. And I call cellForRowAtIndexPath in scrollViewDiddScroll method. It comes back. but It doesn't recurrence because next method called is NSArrayM removeObjectAtIndex instead of trigging the ScrollViewDidScroll method of UIScrollView. and then NSRangeException occurred.
is there anybody meet this or any ideas? thank you.
Your numberOfRowsInSection method of tableview is returns value that is greater than your array of count.
array's count is 3 and you are accessing 5th object of array.
What you can do is put a check to avoid any such crash, just look at this example code. This will be helpful just in case you aren't able to reproduce it.
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
return self.yourArray.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
if (self.yourArray.count > indexPath.row)
{
// your code for the cell
}
return cell;
}
Your counting through an array but you are counting too far, thus not in bounds. You need to count the exact amount of units in the array.
Use this:
[_array count];
Im new to objective C and I was wondering if someone can help me figure out why my app keeps crashing. I believe it has something to do with my Array but I'm not sure how to fix it.. Can someone help please???..
Here's the Log output when it crashes:
2014-11-26 10:37:42.172 SamplePhotoReDo[89697:109203550] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 2 beyond bounds [0 .. 0]'
*** First throw call stack:
(
0 CoreFoundation 0x000000010c75af35 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x000000010c09cbb7 objc_exception_throw + 45
2 CoreFoundation 0x000000010c65301e -[__NSArrayI objectAtIndex:] + 190
3 UIKit 0x000000010d67474a -[UITableViewDataSource tableView:heightForHeaderInSection:] + 39
4 UIKit 0x000000010d221f4e -[UITableView _delegateWantsHeaderForSection:] + 261
5 UIKit 0x000000010d3a6983 -[UISectionRowData refreshWithSection:tableView:tableViewRowData:] + 162
6 UIKit 0x000000010d3ace45 -[UITableViewRowData rectForFooterInSection:heightCanBeGuessed:] + 320
7 UIKit 0x000000010d3acf3a -[UITableViewRowData heightForTable] + 56
8 UIKit 0x000000010d1ffaf0 -[UITableView _updateContentSize] + 381
9 UIKit 0x000000010d21cecd -[UITableView didMoveToWindow] + 65
10 UIKit 0x000000010d1a39a0 -[UIView(Internal) _didMoveFromWindow:toWindow:] + 1482
11 UIKit 0x000000010d1b4333 -[UIScrollView _didMoveFromWindow:toWindow:] + 55
12 UIKit 0x000000010d1a368e -[UIView(Internal) _didMoveFromWindow:toWindow:] + 696
13 UIKit 0x000000010d19c112 __45-[UIView(Hierarchy) _postMovedFromSuperview:]_block_invoke + 125
14 UIKit 0x000000010d19c086 -[UIView(Hierarchy) _postMovedFromSuperview:] + 437
15 UIKit 0x000000010d1a5f4b -[UIView(Internal) _addSubview:positioned:relativeTo:] + 1604
16 UIKit 0x000000010d486534 -[UINavigationTransitionView transition:fromView:toView:] + 479
17 UIKit 0x000000010d2841ef -[UINavigationController _startTransition:fromViewController:toViewController:] + 2967
18 UIKit 0x000000010d284487 -[UINavigationController _startDeferredTransitionIfNeeded:] + 523
19 UIKit 0x000000010d284f47 -[UINavigationController __viewWillLayoutSubviews] + 43
20 UIKit 0x000000010d3ca509 -[UILayoutContainerView layoutSubviews] + 202
21 UIKit 0x000000010d1a8973 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 521
22 QuartzCore 0x000000011052bde8 -[CALayer layoutSublayers] + 150
23 QuartzCore 0x0000000110520a0e _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 380
24 QuartzCore 0x000000011052087e _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 24
25 QuartzCore 0x000000011048e63e _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 242
26 QuartzCore 0x000000011048f74a _ZN2CA11Transaction6commitEv + 390
27 UIKit 0x000000010d12d54d -[UIApplication _reportMainSceneUpdateFinished:] + 44
28 UIKit 0x000000010d12e238 -[UIApplication _runWithMainScene:transitionContext:completion:] + 2642
29 UIKit 0x000000010d12cbf2 -[UIApplication workspaceDidEndTransaction:] + 179
30 FrontBoardServices 0x0000000112f002a3 __31-[FBSSerialQueue performAsync:]_block_invoke + 16
31 CoreFoundation 0x000000010c69053c __CFRUNLOOP_IS_CALLING_OUT_TO_A_BLOCK__ + 12
32 CoreFoundation 0x000000010c686285 __CFRunLoopDoBlocks + 341
33 CoreFoundation 0x000000010c686045 __CFRunLoopRun + 2389
34 CoreFoundation 0x000000010c685486 CFRunLoopRunSpecific + 470
35 UIKit 0x000000010d12c669 -[UIApplication _run] + 413
36 UIKit 0x000000010d12f420 UIApplicationMain + 1282
37 SamplePhotoReDo 0x000000010bb60453 main + 115
38 libdyld.dylib 0x000000010f2d2145 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)'
Here's the code that might be causing the crash:
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
return 1 + self.collectionsFetchResults.count;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
NSInteger numberOfRows = 0;
if (section == 0) {
numberOfRows = 1; // "All Photos" section
} else {
PHFetchResult *fetchResult = self.collectionsFetchResults[section - 1];
numberOfRows = fetchResult.count;
}
return numberOfRows;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell = nil;
NSString *localizedTitle = nil;
if (indexPath.section == 0) {
cell = [tableView dequeueReusableCellWithIdentifier:AllPhotosReuseIdentifier forIndexPath:indexPath];
localizedTitle = NSLocalizedString(#"All Photos", #"");
} else {
cell = [tableView dequeueReusableCellWithIdentifier:CollectionCellReuseIdentifier forIndexPath:indexPath];
PHFetchResult *fetchResult = self.collectionsFetchResults[indexPath.section - 1];
PHCollection *collection = fetchResult[indexPath.row];
localizedTitle = collection.localizedTitle;
}
cell.textLabel.text = localizedTitle;
return cell;
}
- (NSString *)tableView:(UITableView *)tableView titleForHeaderInSection:(NSInteger)section
{
NSString *title = nil;
if (section > 0) {
title = self.collectionsLocalizedTitles[section - 1];
}
return title;
}
#pragma mark - PHPhotoLibraryChangeObserver
- (void)photoLibraryDidChange:(PHChange *)changeInstance
{
// Call might come on any background queue. Re-dispatch to the main queue to handle it.
dispatch_async(dispatch_get_main_queue(), ^{
NSMutableArray *updatedCollectionsFetchResults = nil;
for (PHFetchResult *collectionsFetchResult in self.collectionsFetchResults) {
PHFetchResultChangeDetails *changeDetails = [changeInstance changeDetailsForFetchResult:collectionsFetchResult];
if (changeDetails) {
if (!updatedCollectionsFetchResults) {
updatedCollectionsFetchResults = [self.collectionsFetchResults mutableCopy];
}
[updatedCollectionsFetchResults replaceObjectAtIndex:[self.collectionsFetchResults indexOfObject:collectionsFetchResult] withObject:[changeDetails fetchResultAfterChanges]];
}
}
if (updatedCollectionsFetchResults) {
self.collectionsFetchResults = updatedCollectionsFetchResults;
[self.tableView reloadData];
}
});
}
reason: '*** -[__NSArrayI objectAtIndex:]: index 2 beyond bounds [0 .. 0]'
Quite clear, your array doesn't have as many elements as you think it has. Put a break point at the places where your array is populated and double check it's as expected.
i have problem when i try delete or add object a the list
errror:
2014-09-04 10:59:03.815 DeleteListTest[2781:60b] *** Assertion failure in -[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/UIKit-2935.137/UITableView.m:1368
2014-09-04 10:59:03.856 DeleteListTest[2781:60b] *** 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 (9) must be equal to the number of rows contained in that section before the update (10), plus or minus the number of rows inserted or deleted from that section (0 inserted, 0 deleted) and plus or minus the number of rows moved into or out of that section (0 moved in, 0 moved out).'
*** First throw call stack:
(
0 CoreFoundation 0x01b581e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x018d78e5 objc_exception_throw + 44
2 CoreFoundation 0x01b58048 +[NSException raise:format:arguments:] + 136
3 Foundation 0x014b74de -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 116
4 UIKit 0x0066ff63 -[UITableView _endCellAnimationsWithContext:] + 13402
5 UIKit 0x0067fcea -[UITableView endUpdatesWithContext:] + 51
6 UIKit 0x0067fd18 -[UITableView endUpdates] + 41
7 DeleteListTest 0x00002ece -[MasterViewController leaveEditMode] + 270
8 DeleteListTest 0x0000301a -[MasterViewController tableView:commitEditingStyle:forRowAtIndexPath:] + 202
9 UIKit 0x006916a3 -[UITableView animateDeletionOfRowWithCell:] + 107
10 UIKit 0x0081a595 -[UITableViewCell _swipeDeleteButtonPushed] + 70
11 libobjc.A.dylib 0x018e9880 -[NSObject performSelector:withObject:withObject:] + 77
12 UIKit 0x005993b9 -[UIApplication sendAction:to:from:forEvent:] + 108
13 UIKit 0x00599345 -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 61
14 UIKit 0x0069abd1 -[UIControl sendAction:to:forEvent:] + 66
15 UIKit 0x0069afc6 -[UIControl _sendActionsForEvents:withEvent:] + 577
16 UIKit 0x0069a243 -[UIControl touchesEnded:withEvent:] + 641
17 UIKit 0x0092f2e3 _UIGestureRecognizerUpdate + 7166
18 UIKit 0x005d8a5a -[UIWindow _sendGesturesForEvent:] + 1291
19 UIKit 0x005d9971 -[UIWindow sendEvent:] + 1021
20 UIKit 0x005ab5f2 -[UIApplication sendEvent:] + 242
21 UIKit 0x00595353 _UIApplicationHandleEventQueue + 11455
22 CoreFoundation 0x01ae177f __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
23 CoreFoundation 0x01ae110b __CFRunLoopDoSources0 + 235
24 CoreFoundation 0x01afe1ae __CFRunLoopRun + 910
25 CoreFoundation 0x01afd9d3 CFRunLoopRunSpecific + 467
26 CoreFoundation 0x01afd7eb CFRunLoopRunInMode + 123
27 GraphicsServices 0x03a0a5ee GSEventRunModal + 192
28 GraphicsServices 0x03a0a42b GSEventRun + 104
29 UIKit 0x00597f9b UIApplicationMain + 1225
30 DeleteListTest 0x00004a4d main + 141
31 libdyld.dylib 0x0219f701 start + 1
32 ??? 0x00000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
this is the delete method
if(editingStyle == UITableViewCellEditingStyleDelete){
[tableTitles removeObjectAtIndex:[indexPath row]];
[self leaveEditMode];
[[self tableView] reloadData];
someone can help me ? thx u :)
I believe you are missing the call to:
[self.tableView deleteRowsAtIndexPaths:indexPath
withRowAnimation:UITableViewRowAnimationFade];
and you don't need the reloadData call:
if (editingStyle == UITableViewCellEditingStyleDelete) {
[tableTitles removeObjectAtIndex:[indexPath row]];
[self.tableView deleteRowsAtIndexPaths:#[indexPath]
withRowAnimation:UITableViewRowAnimationFade];
[self leaveEditMode];
(this will also look better as it will give visual feedback to the user; unlike reloadData).
This question already has answers here:
Assertion failure in dequeueReusableCellWithIdentifier:forIndexPath:
(22 answers)
Closed 8 years ago.
here's the method causing the problem:
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"TableCell";
TableCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier
forIndexPath:indexPath];
// Configure the cell...
int row = [indexPath row];
Books *book = [myBooks objectAtIndex:row];
cell.bookName.text = book.bookName;
return cell;
}
full log:
2014-02-05 23:19:09.458 Books[1425:a0b] *** Assertion failure in -[UITableView dequeueReusableCellWithIdentifier:forIndexPath:], /SourceCache/UIKit_Sim/UIKit-2903.2/UITableView.m:5251
2014-02-05 23:19:09.471 Books[1425:a0b] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'unable to dequeue a cell with identifier TableCell - must register a nib or a class for the identifier or connect a prototype cell in a storyboard'
*** First throw call stack:
(
0 CoreFoundation 0x017395e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x014bc8b6 objc_exception_throw + 44
2 CoreFoundation 0x01739448 +[NSException raise:format:arguments:] + 136
3 Foundation 0x0109d23e -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 116
4 UIKit 0x003135e3 -[UITableView dequeueReusableCellWithIdentifier:forIndexPath:] + 170
5 Books 0x000032df -[TableViewController tableView:cellForRowAtIndexPath:] + 127
6 UIKit 0x0031dd2f -[UITableView _createPreparedCellForGlobalRow:withIndexPath:] + 412
7 UIKit 0x0031de03 -[UITableView _createPreparedCellForGlobalRow:] + 69
8 UIKit 0x00302124 -[UITableView _updateVisibleCellsNow:] + 2378
9 UIKit 0x003155a5 -[UITableView layoutSubviews] + 213
10 UIKit 0x00299dd7 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 355
11 libobjc.A.dylib 0x014ce81f -[NSObject performSelector:withObject:] + 70
12 QuartzCore 0x03af372a -[CALayer layoutSublayers] + 148
13 QuartzCore 0x03ae7514 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 380
14 QuartzCore 0x03af3675 -[CALayer layoutIfNeeded] + 160
15 UIKit 0x00354ca3 -[UIViewController window:setupWithInterfaceOrientation:] + 304
16 UIKit 0x00273d27 -[UIWindow _setRotatableClient:toOrientation:updateStatusBar:duration:force:isRotating:] + 5212
17 UIKit 0x002728c6 -[UIWindow _setRotatableClient:toOrientation:updateStatusBar:duration:force:] + 82
18 UIKit 0x00272798 -[UIWindow _setRotatableViewOrientation:updateStatusBar:duration:force:] + 117
19 UIKit 0x00272820 -[UIWindow _setRotatableViewOrientation:duration:force:] + 67
20 UIKit 0x002718ba __57-[UIWindow _updateToInterfaceOrientation:duration:force:]_block_invoke + 120
21 UIKit 0x0027181c -[UIWindow _updateToInterfaceOrientation:duration:force:] + 400
22 UIKit 0x00272573 -[UIWindow setAutorotates:forceUpdateInterfaceOrientation:] + 870
23 UIKit 0x00275b66 -[UIWindow setDelegate:] + 449
24 UIKit 0x00346dc7 -[UIViewController _tryBecomeRootViewControllerInWindow:] + 180
25 UIKit 0x0026b7cc -[UIWindow addRootViewControllerViewIfPossible] + 609
26 UIKit 0x0026b947 -[UIWindow _setHidden:forced:] + 312
27 UIKit 0x0026bbdd -[UIWindow _orderFrontWithoutMakingKey] + 49
28 UIKit 0x0027644a -[UIWindow makeKeyAndVisible] + 65
29 UIKit 0x002298e0 -[UIApplication _callInitializationDelegatesForURL:payload:suspended:] + 1851
30 UIKit 0x0022dfb8 -[UIApplication _runWithURL:payload:launchOrientation:statusBarStyle:statusBarHidden:] + 824
31 UIKit 0x0024242c -[UIApplication handleEvent:withNewEvent:] + 3447
32 UIKit 0x00242999 -[UIApplication sendEvent:] + 85
33 UIKit 0x0022fc35 _UIApplicationHandleEvent + 736
34 GraphicsServices 0x0368c2eb _PurpleEventCallback + 776
35 GraphicsServices 0x0368bdf6 PurpleEventCallback + 46
36 CoreFoundation 0x016b4dd5 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 53
37 CoreFoundation 0x016b4b0b __CFRunLoopDoSource1 + 523
38 CoreFoundation 0x016df7ec __CFRunLoopRun + 2156
39 CoreFoundation 0x016deb33 CFRunLoopRunSpecific + 467
40 CoreFoundation 0x016de94b CFRunLoopRunInMode + 123
41 UIKit 0x0022d6ed -[UIApplication _run] + 840
42 UIKit 0x0022f94b UIApplicationMain + 1225
43 Books 0x000038bd main + 141
44 libdyld.dylib 0x01d75725 start + 0
45 ??? 0x00000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
You can directly set the identifier using the storyboard like this.
From the documentation:
Important: You must register a class or nib file using the
registerNib:forCellReuseIdentifier: or
registerClass:forCellReuseIdentifier: method before calling this
method.
You need to register the cell as a usable class for that identifier. Call this after you initialize your UITableView (probably in viewDidLoad)
[self.tableView registerClass:[TableCell class] forCellReuseIdentifier:CellIdentifier]
This assumes CellIdentifier has been moved somewhere where it can be accessed from here.
Try this:
-(UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"TableCell";
TableCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if(!cell)
{
cell = [[[TableCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
}
// Configure the cell...
int row = [indexPath row];
Books *book = [myBooks objectAtIndex:row];
cell.bookName.text = book.bookName;
return cell;
}
I design the process is that:
Enter into a CourseAddViewController(UITableViewController) via a Model Segue;
The right bar button display "Done"(At this status, the tableview display all data in eachrow with "-", but the additional row at the bottom with "+");
Press "Done" button, the save the data.
When I add the statement "self.editing = YES;" in - (void)viewDidLoad method, it will crash.
I found that it didn't perform "tableView:cellForRowAtIndexPath:" method.But, actually I trust that there is 1 row in section 0 via the result of NSLog().
If I don't add "self.editing = YES;", it run correctly.
- (void)viewDidLoad
{
[super viewDidLoad];
self.navigationItem.rightBarButtonItem = self.editButtonItem;
self.editing = YES; // here: adding it cause crash
}
After performing "insertRowsAtIndexPaths:withRowAnimation:", it crashed.
Two statement:
[self.tableView beginUpdates];
[self.tableView endUpdates];
add them or not, all cuase crash.
- (void)setEditing:(BOOL)editing animated:(BOOL)animated
{
[super setEditing:editing animated:animated];
[self.tableView beginUpdates];
NSInteger booksCount = self.course.books.count;
NSArray *booksInsertIndexPath = [NSArray arrayWithObject:[NSIndexPath indexPathForRow:booksCount inSection:0]];
if (editing) {
[self.tableView insertRowsAtIndexPaths:booksInsertIndexPath
withRowAnimation:UITableViewRowAnimationBottom]; // then, it crashes
} else {
[self.tableView deleteRowsAtIndexPaths:booksInsertIndexPath
withRowAnimation:UITableViewRowAnimationBottom];
}
[self.tableView endUpdates];
// ...
}
Other method,
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
{
NSLog(#"%d", self.fetchedResultsController.sections.count); // the result is always 1;
return self.fetchedResultsController.sections.count;
}
Other method,
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
{
id <NSFetchedResultsSectionInfo> sectionInfo = [self.fetchedResultsController.sections objectAtIndex:section];
NSInteger rows = [sectionInfo numberOfObjects];
if (self.editing)
rows++;
NSLog(#"%d", rows); // the result is always 1;
return rows;
}
Other method,
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (!cell)
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:CellIdentifier];
id <NSFetchedResultsSectionInfo> sectionInfo = [self.fetchedResultsController.sections objectAtIndex:indexPath.section];
NSInteger rows = [sectionInfo numberOfObjects];
if (self.editing && rows == indexPath.row) {
return cell;
}
[self configureCell:cell atIndexPath:indexPath];
// NSLog(#"%d-%d-%d-%d", self.editing, rows, indexPath.section, indexPath.row);
return cell;
}
New Edit:
2012-10-27 08:44:29.934 Course Table[306:fb03] *** Assertion failure in
-[UITableView _endCellAnimationsWithContext:], /SourceCache/UIKit_Sim/
UIKit-914.84/UITableView.m:1037
2012-10-27 08:44:29.935 Course Table[306:fb03] CRASH: Invalid update:
invalid number of rows in section 0. The number of rows contained in
an existing section after the update (1) must be equal to the number
of rows contained in that section before the update (1), plus or
minus the number of rows inserted or deleted from that section
(1 inserted, 0 deleted) and plus or minus the number of rows moved
into or out of that section (0 moved in, 0 moved out).
2012-10-27 08:44:29.942 Course Table[306:fb03] Stack Trace: (
0 CoreFoundation 0x016cf03e __exceptionPreprocess + 206
1 libobjc.A.dylib 0x01860cd6 objc_exception_throw + 44
2 CoreFoundation 0x01677a48 +[NSException raise:format:arguments:] + 136
3 Foundation 0x009d12cb -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 116
4 UIKit 0x000bf3d7 -[UITableView(_UITableViewPrivate) _endCellAnimationsWithContext:] + 12439
5 UIKit 0x000ca6d2 -[UITableView _updateRowsAtIndexPaths:updateAction:withRowAnimation:] + 295
6 UIKit 0x000ca711 -[UITableView insertRowsAtIndexPaths:withRowAnimation:] + 55
7 Course Table 0x0000ef42 -[CTXCourseAddViewController setEditing:animated:] + 434
8 UIKit 0x0010de4c -[UIViewController(UINavigationControllerItem) setEditing:] + 49
9 Course Table 0x0000ec1f -[CTXCourseAddViewController viewDidLoad] + 655
10 UIKit 0x00101a1e -[UIViewController view] + 184
11 UIKit 0x00100fec -[UIViewController nextResponder] + 34
12 UIKit 0x00127f1d -[UIResponder _containsResponder:] + 40
13 UIKit 0x001121cb -[UINavigationController defaultFirstResponder] + 83
14 UIKit 0x00128df1 -[UIResponder(Internal) _deepestDefaultFirstResponder] + 36
15 UIKit 0x00128ea9 -[UIResponder(Internal) _promoteDeepestDefaultFirstResponder] + 36
16 UIKit 0x00322508 -[UIWindowController transitionViewDidStart:] + 89
17 UIKit 0x000df401 -[UITransitionView _didStartTransition] + 93
18 UIKit 0x000e008b -[UITransitionView transition:fromView:toView:] + 1169
19 UIKit 0x00321d6c -[UIWindowController transition:fromViewController:toViewController:target:didEndSelector:] + 6114
20 UIKit 0x00108857 -[UIViewController presentViewController:withTransition:completion:] + 3579
21 UIKit 0x001089bc -[UIViewController presentViewController:animated:completion:] + 112
22 UIKit 0x001089fc -[UIViewController presentModalViewController:animated:] + 56
23 UIKit 0x00470f4a -[UIStoryboardModalSegue perform] + 250
24 UIKit 0x004654d0 -[UIStoryboardSegueTemplate perform:] + 174
25 CoreFoundation 0x016d0e99 -[NSObject performSelector:withObject:withObject:] + 73
26 UIKit 0x0003d14e -[UIApplication sendAction:to:from:forEvent:] + 96
27 UIKit 0x0027ba0e -[UIBarButtonItem(UIInternal) _sendAction:withEvent:] + 145
28 CoreFoundation 0x016d0e99 -[NSObject performSelector:withObject:withObject:] + 73
29 UIKit 0x0003d14e -[UIApplication sendAction:to:from:forEvent:] + 96
30 UIKit 0x0003d0e6 -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 61
31 UIKit 0x000e3ade -[UIControl sendAction:to:forEvent:] + 66
32 UIKit 0x000e3fa7 -[UIControl(Internal) _sendActionsForEvents:withEvent:] + 503
33 UIKit 0x000e3266 -[UIControl touchesEnded:withEvent:] + 549
34 UIKit 0x000623c0 -[UIWindow _sendTouchesForEvent:] + 513
35 UIKit 0x000625e6 -[UIWindow sendEvent:] + 273
36 UIKit 0x00048dc4 -[UIApplication sendEvent:] + 464
37 UIKit 0x0003c634 _UIApplicationHandleEvent + 8196
38 GraphicsServices 0x015b9ef5 PurpleEventCallback + 1274
39 CoreFoundation 0x016a3195 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE1_PERFORM_FUNCTION__ + 53
40 CoreFoundation 0x01607ff2 __CFRunLoopDoSource1 + 146
41 CoreFoundation 0x016068da __CFRunLoopRun + 2218
42 CoreFoundation 0x01605d84 CFRunLoopRunSpecific + 212
43 CoreFoundation 0x01605c9b CFRunLoopRunInMode + 123
44 GraphicsServices 0x015b87d8 GSEventRunModal + 190
45 GraphicsServices 0x015b888a GSEventRun + 103
46 UIKit 0x0003a626 UIApplicationMain + 1163
47 Course Table 0x000020dd main + 141
48 Course Table 0x00002045 start + 53
)
2012-10-27 08:44:29.945 Course Table[306:fb03] *** 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 (1) must be equal to the number
of rows contained in that section before the update (1), plus or minus
the number of rows inserted or deleted from that section (1 inserted,
0 deleted) and plus or minus the number of rows moved into or out of that
section (0 moved in, 0 moved out).
terminate called throwing an exception(lldb)
Just add
[self.tableView reloadData];
before
self.editing = YES;
This is needed because the table view doesn't initially have information about its data source and delegate; if you create a table view, it always needs to be sent a reloadData message as part of its initialization.