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.
Related
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.
I have a UITableviewController with 2 sections and each one have 1 custom cell. On the second static cell, I have dropped a UITableview and implemented the delegates accordingly.
Code snippet.
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
if (tableView == self.activityTable) { // dynamic table
return 1;
}else {
return 2;
}
}
-(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
if (tableView == self.activityTable) { // dynamic tableview
return [self.fetchActivityController.fetchedObjects count];
}else {
return 1; //static tableview
}
}
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
if (tableView == self.activityTable) {
if ([self.fetchActivityController.fetchedObjects count] == 0)
return nil;
ADNetworkCell *cell=[self.activityTable dequeueReusableCellWithIdentifier:NSStringFromClass([ADNetworkCell class])];
ADActivity* activityObj = (ADActivity*)[self.fetchActivityController.fetchedObjects objectAtIndex:indexPath.row];
ADUser* nUser = [activityObj networkAgent];
[cell configWithAgent:nUser withActivity:[activityObj activity]];
cell.activityText.delegate=self;
return cell;
}else { // static tableview code
return [super tableView:tableView cellForRowAtIndexPath:indexPath];
}
}
-(CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath{
if (tableView == self.activityTable) {
return 95.0f;
} else {
// The height of the 2nd static cell should be size of tableview with dynamic cell.
if (indexPath.section == 1) {
return 95 * [self.activityArray count];
}
}
return 44.0f;
}
Its crashing
uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI
objectAtIndex:]: index 1 beyond bounds [0 .. 0]'
*** First throw call stack: ( 0 CoreFoundation 0x000000010d0b8f45 exceptionPreprocess + 165
1 libobjc.A.dylib 0x000000010c60bdeb objc_exception_throw + 48
2 CoreFoundation 0x000000010cfa7b14 -[__NSArrayI objectAtIndex:] + 164
3 UIKit 0x000000010b179516 -[UITableViewDataSource tableView:indentationLevelForRowAtIndexPath:] + 160
4 UIKit 0x000000010ae4929b -[UITableViewController tableView:indentationLevelForRowAtIndexPath:] + 65
5 UIKit 0x000000010abb7325 __53-[UITableView _configureCellForDisplay:forIndexPath:]_block_invoke + 2226
6 UIKit 0x000000010ab15c10 +[UIView(Animation) performWithoutAnimation:] + 65
7 UIKit 0x000000010abb6a5a -[UITableView _configureCellForDisplay:forIndexPath:] + 475
8 UIKit 0x000000010abc1e58 -[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 828
9 UIKit 0x000000010abc1f3f -[UITableView _createPreparedCellForGlobalRow:willDisplay:] + 74
10 UIKit 0x000000010ab97307 -[UITableView _updateVisibleCellsNow:isRecursive:] + 3187
11 UIKit 0x000000010abcad1c -[UITableView _performWithCachedTraitCollection:] + 92
12 UIKit 0x000000010abb2884 -[UITableView layoutSubviews] + 223
13 UIKit 0x000000010ab20e40 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 710
14 QuartzCore 0x000000010a7ec59a -[CALayer layoutSublayers] + 146
15 QuartzCore 0x000000010a7e0e70 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 366
16 QuartzCore 0x000000010a7e0cee _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 24
17 QuartzCore 0x000000010a7d5475 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 277
18 QuartzCore 0x000000010a802c0a _ZN2CA11Transaction6commitEv + 486
19 UIKit 0x000000010aa66ca4 _UIApplicationHandleEventQueue + 7329
20 CoreFoundation 0x000000010cfe5011 __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION + 17
21 CoreFoundation 0x000000010cfdaf3c __CFRunLoopDoSources0 + 556
22 CoreFoundation 0x000000010cfda3f3 __CFRunLoopRun + 867
23 CoreFoundation 0x000000010cfd9e08 CFRunLoopRunSpecific + 488
24 GraphicsServices 0x000000010e733ad2 GSEventRunModal + 161
25 UIKit 0x000000010aa6c30d UIApplicationMain + 171
26 Agentdesks 0x000000010863164f main + 111
27 libdyld.dylib 0x000000010d59c92d start + 1 28 ???
0x0000000000000001 0x0 + 1 ) libc++abi.dylib: terminating with
uncaught exception of type NSException (lldb)
I have a tableView which should load its cells with data from server.
When my data is loaded from server I call [self.tableView reloadData] inside completionhandler block.
So the method cellForRowAtIndexPath gets called again.
My implementation for cellForRowAtIndexPath is this:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
// Configure the cell...
NewsCell* cell = [self.tableView dequeueReusableCellWithIdentifier:#"NewsCell" forIndexPath:indexPath];
if(!cell){
cell = [[NewsCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:#"NewsCell"];
}
News* currentNews = (News*)[self.newsList objectAtIndex:indexPath.row];
cell.newsTitle.text = currentNews.title;
// cell.newsTitle.text = #"salam";
return cell;
}
Note: self.newsList is an array that is populated with data from server
The code that parses response json from server is this:
[GNetworkHelper getJsonDataFromURL:urlString
withCompletionHandler:^(NSDictionary * jsonResponse) {
// Parse retrieved json and pass it to completion handler;;
NSMutableArray* news = [[NSMutableArray alloc] init];
if (jsonResponse) {
for (NSDictionary* new in jsonResponse) {
News *currentNew = [[News alloc] initWithDictionary:new];
[news addObject:currentNew];
}
}else{
News* testNew = [[News alloc] init];
[testNew setTitle:#"salam"];
[news addObject:testNew];
}
completionHandler(news);
}];
My problem: When I debug this code the cell variable I create using dequeueReusableCellWithIdentifier:forIndexPath function is null in the debugger's variables section, but when I use lldb command po to print it out I get this
(lldb) po cell
<NewsCell: 0x7fc5fadb2ee0; baseClass = UITableViewCell; frame = (0 0; 375 143); autoresize = W; layer = <CALayer: 0x7fc5fad9fcd0>>
The same happens for currentNews variable. For it I get this from po command
(lldb) po currentNews
<News: 0x7fc5fd0480d0>
I even can get properties on it like this:
(lldb) po currentNews.title
<__NSCFArray 0x7fc5fd047300>(
"some title"
)
There is no exception when stepping through this method's statements. But when the method returns the Unrecognized Selector exception is thrown
Why this happens??
The Strange thing is that if I change this line:
cell.newsTitle.text = currentNews.title;
to this:
cell.newsTitle.text = #"Some test text";
everything goes well, specifically the cell and currentNews variables are not null anymore and tableView renders the cells without any problem
The full stack trace is :
[__NSCFArray length]: unrecognized selector sent to instance 0x7fc5fd047300
2015-09-16 11:30:40.630 Gallery[12013:952548] Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[__NSCFArray length]: unrecognized selector sent to instance 0x7fc5fd047300'
--- First throw call stack:
(
0 CoreFoundation 0x0000000105af3f35 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x000000010578cbb7 objc_exception_throw + 45
2 CoreFoundation 0x0000000105afb04d -[NSObject(NSObject) doesNotRecognizeSelector:] + 205
3 CoreFoundation 0x0000000105a5327c ___forwarding___ + 988
4 CoreFoundation 0x0000000105a52e18 _CF_forwarding_prep_0 + 120
5 UIKit 0x00000001060a5f45 -[UILabel _textRectForBounds:limitedToNumberOfLines:includingShadow:] + 65
6 UIKit 0x00000001060a5da0 -[UILabel textRectForBounds:limitedToNumberOfLines:] + 76
7 UIKit 0x00000001060a9852 -[UILabel _intrinsicSizeWithinSize:] + 170
8 UIKit 0x00000001060a9932 -[UILabel intrinsicContentSize] + 76
9 UIKit 0x000000010655fea4 -[UIView(UIConstraintBasedLayout) _generateContentSizeConstraints] + 33
10 UIKit 0x000000010655fc64 -[UIView(UIConstraintBasedLayout) _updateContentSizeConstraints] + 422
11 UIKit 0x00000001065670d6 -[UIView(AdditionalLayoutSupport) updateConstraints] + 163
12 UIKit 0x00000001060a979d -[UILabel updateConstraints] + 272
13 UIKit 0x00000001065666fa -[UIView(AdditionalLayoutSupport) _internalUpdateConstraintsIfNeededAccumulatingViewsNeedingSecondPassAndViewsNeedingBaselineUpdate:] + 248
14 UIKit 0x00000001065668f2 -[UIView(AdditionalLayoutSupport) _updateConstraintsIfNeededAccumulatingViewsNeedingSecondPassAndViewsNeedingBaselineUpdate:] + 124
15 CoreFoundation 0x00000001059fc194 CFArrayApplyFunction + 68
16 UIKit 0x000000010656669b -[UIView(AdditionalLayoutSupport) _internalUpdateConstraintsIfNeededAccumulatingViewsNeedingSecondPassAndViewsNeedingBaselineUpdate:] + 153
17 Foundation 0x0000000105332d6e -[NSISEngine withBehaviors:performModifications:] + 155
18 UIKit 0x00000001065668f2 -[UIView(AdditionalLayoutSupport) _updateConstraintsIfNeededAccumulatingViewsNeedingSecondPassAndViewsNeedingBaselineUpdate:] + 124
19 CoreFoundation 0x00000001059fc194 CFArrayApplyFunction + 68
20 UIKit 0x000000010656669b -[UIView(AdditionalLayoutSupport) _internalUpdateConstraintsIfNeededAccumulatingViewsNeedingSecondPassAndViewsNeedingBaselineUpdate:] + 153
21 UIKit 0x00000001065668f2 -[UIView(AdditionalLayoutSupport) _updateConstraintsIfNeededAccumulatingViewsNeedingSecondPassAndViewsNeedingBaselineUpdate:] + 124
22 UIKit 0x0000000106566dbe __60-[UIView(AdditionalLayoutSupport) updateConstraintsIfNeeded]_block_invoke + 96
23 UIKit 0x0000000106566a86 -[UIView(AdditionalLayoutSupport) updateConstraintsIfNeeded] + 231
24 UIKit 0x000000010635c8b8 -[UITableViewCellContentView updateConstraintsIfNeeded] + 95
25 UIKit 0x000000010656719e -[UIView(AdditionalLayoutSupport) _updateConstraintsAtEngineLevelIfNeeded] + 159
26 UIKit 0x0000000105f4db2d -[UIView(Hierarchy) _updateConstraintsAsNecessaryAndApplyLayoutFromEngine] + 114
27 UIKit 0x0000000105f59973 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 521
28 QuartzCore 0x000000010504ade8 -[CALayer layoutSublayers] + 150
29 QuartzCore 0x000000010503fa0e _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 380
30 QuartzCore 0x000000010503f87e _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 24
31 QuartzCore 0x0000000104fad63e _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 242
32 QuartzCore 0x0000000104fae74a _ZN2CA11Transaction6commitEv + 390
33 QuartzCore 0x0000000104faedb5 _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 89
34 CoreFoundation 0x0000000105a28dc7 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
35 CoreFoundation 0x0000000105a28d20 __CFRunLoopDoObservers + 368
36 CoreFoundation 0x0000000105a1eb53 __CFRunLoopRun + 1123
37 CoreFoundation 0x0000000105a1e486 CFRunLoopRunSpecific + 470
38 GraphicsServices 0x00000001085d29f0 GSEventRunModal + 161
39 UIKit 0x0000000105ee0420 UIApplicationMain + 1282
40 Gallery 0x000000010346ded3 main + 115
41 libdyld.dylib 0x0000000107325145 start + 1
42 ??? 0x0000000000000001 0x0 + 1
)
Can anybody tell me the reason for this?
The server JSON is an array of a string, ["some title"], and you expect it to be just a string "some title".
Try adding an assertion so that your parsing of the server data is correct.
News* currentNews = (News*)[self.newsList objectAtIndex:indexPath.row];
NSAssert([currentNews.title isKindOfClass:[NSString class]],
#"Title is not a string but a %#.",
NSStringFromClass([currentNews.title class]));
cell.newsTitle.text = currentNews.title;
It simply indicates at some point when you try to access title value in currentNews object, it would be null. thats why your app throws exception. put a condition to check null value.
Use following method to check any value/object exist or not.
Usage
write following code in your cellForRowAtIndexPath method.
if([self isEmpty:currentNews.title])
{
cell.newsTitle.text = #"default value";
}
else
{
cell.newsTitle.text = currentNews.title[0];
}
// Method to check empty value/object
- (BOOL)isEmpty:(id)object
{
return object == nil
|| [object isKindOfClass:[NSNull class]]
|| ([object respondsToSelector:#selector(length)]
&& [(NSData *)object length] == 0)
|| ([object respondsToSelector:#selector(count)]
&& [(NSArray *)object count] == 0);
}
I have a static UItableView. In one of the cells, I have a dynamic prototype UITableView. Here is the code I implemented:
In viewDidLoad:
self.tagsArray = [[NSArray alloc] initWithObjects:#"hey", #"what", #"ola", #"dada", #"hoster", #"umi", nil];
- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
return self.tableView == tableView ? 2 : 1;
}
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
if (self.tableView == tableView)
return (section == 0) ? 3 : 2;
else
return [self.tagsArray count];
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
UITableViewCell *cell;
if (self.tableView == tableView) {
cell = [super tableView:tableView cellForRowAtIndexPath:indexPath];
}
else {
cell = [tableView dequeueReusableCellWithIdentifier:#"cell" forIndexPath:indexPath];
[cell.textLabel setText:self.tagsArray [indexPath.row]];
}
return cell;
}
When I run the app, everything works fine. But when I start scrolling on the inner tableView (the dynamic prototype one), then I get the following error:
Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 3 beyond bounds [0 .. 2]'
*** First throw call stack:
(
0 CoreFoundation 0x00000001012a7c65 __exceptionPreprocess + 165
1 libobjc.A.dylib 0x0000000100f40bb7 objc_exception_throw + 45
2 CoreFoundation 0x000000010119e17e -[__NSArrayI objectAtIndex:] + 190
3 UIKit 0x0000000101e12132 -[UITableViewDataSource tableView:indentationLevelForRowAtIndexPath:] + 106
4 UIKit 0x00000001019dc1f9 __53-[UITableView _configureCellForDisplay:forIndexPath:]_block_invoke + 1711
5 UIKit 0x000000010195a68e +[UIView(Animation) performWithoutAnimation:] + 65
6 UIKit 0x00000001019dbb3b -[UITableView _configureCellForDisplay:forIndexPath:] + 312
7 UIKit 0x00000001019e3a41 -[UITableView _createPreparedCellForGlobalRow:withIndexPath:willDisplay:] + 533
8 UIKit 0x00000001019c2248 -[UITableView _updateVisibleCellsNow:isRecursive:] + 2853
9 UIKit 0x00000001019d88a9 -[UITableView layoutSubviews] + 210
10 UIKit 0x0000000101962a2b -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 536
11 QuartzCore 0x0000000100934ec2 -[CALayer layoutSublayers] + 146
12 QuartzCore 0x00000001009296d6 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 380
13 QuartzCore 0x0000000100929546 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 24
14 QuartzCore 0x0000000100895886 _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 242
15 QuartzCore 0x0000000100896a3a _ZN2CA11Transaction6commitEv + 462
16 QuartzCore 0x00000001008970eb _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 89
17 CoreFoundation 0x00000001011daca7 __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 23
18 CoreFoundation 0x00000001011dac00 __CFRunLoopDoObservers + 368
19 CoreFoundation 0x00000001011d0a33 __CFRunLoopRun + 1123
20 CoreFoundation 0x00000001011d0366 CFRunLoopRunSpecific + 470
21 GraphicsServices 0x000000010510da3e GSEventRunModal + 161
22 UIKit 0x00000001018e2900 UIApplicationMain + 1282
23 myApp 0x00000001004cf51f main + 111
24 libdyld.dylib 0x0000000102cfe145 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
I don't know what the above error means, but I think that it's not creating new cells for some reason, and because of that, it has a conflict with the number of cells to display, so it crashes with the above error.
Why isn't the inner tableView creating new cells, and what can I do to fix it?
What the error is telling you is that you tried to access an element that doesn't exist.
Your data array only has 2 elements, but you are hardcoding the amount of cells you want to create (3) so when it looks for the 3rd element to create the cell it crashes because is not existent.
I have an iOS app that has been working quite well in two languages – I know added some stuff, already keeping in mind using NSLocalizedString for localization etc. The english version of the app works fine so far, but the second language version crashes right after starting. Why?
One should note that I have not added all NSLocalizedStrings in my localizable.strings file. Furthermore, I have two separate Storyboards for both english an german. Any help would be greatly appreciated!
2014-12-18 18:14:36.083 Coverdale[48297:60b] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayI objectAtIndex:]: index 2 beyond bounds [0 .. 1]'
*** First throw call stack:
(
0 CoreFoundation 0x002461e4 __exceptionPreprocess + 180
1 libobjc.A.dylib 0x020538e5 objc_exception_throw + 44
2 CoreFoundation 0x001fa8b2 -[__NSArrayI objectAtIndex:] + 210
3 UIKit 0x0126a35f -[UITableViewDataSource tableView:indentationLevelForRowAtIndexPath:] + 127
4 UIKit 0x00fe3f34 -[UITableViewController tableView:indentationLevelForRowAtIndexPath:] + 61
5 UIKit 0x00e012cf __53-[UITableView _configureCellForDisplay:forIndexPath:]_block_invoke + 1786
6 UIKit 0x00d7581f +[UIView(Animation) performWithoutAnimation:] + 82
7 UIKit 0x00d75868 +[UIView(Animation) _performWithoutAnimation:] + 40
8 UIKit 0x00e00bd0 -[UITableView _configureCellForDisplay:forIndexPath:] + 108
9 UIKit 0x00e0813d -[UITableView _createPreparedCellForGlobalRow:withIndexPath:] + 442
10 UIKit 0x00e081f3 -[UITableView _createPreparedCellForGlobalRow:] + 69
11 UIKit 0x00de9ece -[UITableView _updateVisibleCellsNow:] + 2428
12 UIKit 0x00dfe6a5 -[UITableView layoutSubviews] + 213
13 UIKit 0x00d7e964 -[UIView(CALayerDelegate) layoutSublayersOfLayer:] + 355
14 libobjc.A.dylib 0x0206582b -[NSObject performSelector:withObject:] + 70
15 QuartzCore 0x007c845a -[CALayer layoutSublayers] + 148
16 QuartzCore 0x007bc244 _ZN2CA5Layer16layout_if_neededEPNS_11TransactionE + 380
17 QuartzCore 0x007bc0b0 _ZN2CA5Layer28layout_and_display_if_neededEPNS_11TransactionE + 26
18 QuartzCore 0x007227fa _ZN2CA7Context18commit_transactionEPNS_11TransactionE + 294
19 QuartzCore 0x00723b85 _ZN2CA11Transaction6commitEv + 393
20 QuartzCore 0x00724258 _ZN2CA11Transaction17observer_callbackEP19__CFRunLoopObservermPv + 92
21 CoreFoundation 0x0020e36e __CFRUNLOOP_IS_CALLING_OUT_TO_AN_OBSERVER_CALLBACK_FUNCTION__ + 30
22 CoreFoundation 0x0020e2bf __CFRunLoopDoObservers + 399
23 CoreFoundation 0x001ec254 __CFRunLoopRun + 1076
24 CoreFoundation 0x001eb9d3 CFRunLoopRunSpecific + 467
25 CoreFoundation 0x001eb7eb CFRunLoopRunInMode + 123
26 GraphicsServices 0x0406b5ee GSEventRunModal + 192
27 GraphicsServices 0x0406b42b GSEventRun + 104
28 UIKit 0x00d0ff9b UIApplicationMain + 1225
29 Coverdale 0x0009b95d main + 141
30 libdyld.dylib 0x028b9701 start + 1
31 ??? 0x00000001 0x0 + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
(lldb)
EDIT
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
static NSString *CellIdentifier = #"Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
if (cell == nil) {
cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
}
cell.textLabel.text = #"Error";
if (indexPath.section == 0) {
if(indexPath.row == 0)
{ /*..*/}
}
return cell;
}
Turns out I needed to implement indentationLevelForRowAtIndexPath and just return 0.