README and documentationIGListKit version: 3.0Hello Guys,
I'm receiving this exception in crashlytics, Unfortunately I couldn't reproduce it in my end to follow up. Although this is the stacktrace:
Fatal Exception: NSRangeException
0 CoreFoundation 0x182f26db0 __exceptionPreprocess
1 libobjc.A.dylib 0x18258bf80 objc_exception_throw
2 CoreFoundation 0x182e06dfc -[__NSArrayM removeObjectAtIndex:]
3 UIKit 0x18892f560 -[_UIFlowLayoutSection setSize:forItemAtIndexPath:]
4 UIKit 0x1889318c4 -[_UIFlowLayoutInfo setSize:forItemAtIndexPath:]
5 UIKit 0x1888ea460 -[UICollectionViewFlowLayout invalidationContextForPreferredLayoutAttributes:withOriginalAttributes:]
6 UIKit 0x1888c6f90 -[UICollectionView _checkForPreferredAttributesInView:originalAttributes:]
7 UIKit 0x1888c7650 -[UICollectionView _createPreparedCellForItemAtIndexPath:withLayoutAttributes:applyAttributes:isFocused:]
8 UIKit 0x1888d3cd0 __51-[UICollectionView _viewAnimationsForCurrentUpdate]_block_invoke1586
9 UIKit 0x18826d868 -[UICollectionView _viewAnimationsForCurrentUpdate]
10 UIKit 0x1888d58cc __62-[UICollectionView _updateWithItems:tentativelyForReordering:]_block_invoke1656
11 UIKit 0x1880935b4 +[UIView(Animation) performWithoutAnimation:]
12 UIKit 0x1888d4f18 -[UICollectionView _updateWithItems:tentativelyForReordering:]
13 UIKit 0x1888d30d4 -[UICollectionView _endItemAnimationsWithInvalidationContext:tentativelyForReordering:]
14 UIKit 0x1888d6464 -[UICollectionView _performBatchUpdates:completion:invalidationContext:tentativelyForReordering:]
15 UIKit 0x1888d62e0 -[UICollectionView _performBatchUpdates:completion:invalidationContext:]
16 UIKit 0x1882742a4 -[UICollectionView performBatchUpdates:completion:]
17 MyApplication 0x10017853c __62-[IGListAdapterUpdater performBatchUpdatesWithCollectionView:]_block_invoke.97 (IGListAdapterUpdater.m:232)
18 MyApplication 0x100177af0 -[IGListAdapterUpdater performBatchUpdatesWithCollectionView:] (IGListAdapterUpdater.m:263)
19 MyApplication 0x1001796e8 __54-[IGListAdapterUpdater queueUpdateWithCollectionView:]_block_invoke (IGListAdapterUpdater.m:392)
20 libdispatch.dylib 0x1829714bc _dispatch_call_block_and_release
21 libdispatch.dylib 0x18297147c _dispatch_client_callout
22 libdispatch.dylib 0x182976b84 _dispatch_main_queue_callback_4CF
23 CoreFoundation 0x182edcd50 __CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE__
24 CoreFoundation 0x182edabb8 __CFRunLoopRun
25 CoreFoundation 0x182e04c50 CFRunLoopRunSpecific
26 GraphicsServices 0x1846ec088 GSEventRunModal
27 UIKit 0x1880ee088 UIApplicationMain
28 MyApplication 0x1000ad780 main (main.m:15)
29 libdispatch.dylib 0x1829a28b8 (Missing)
With exception:
Fatal Exception: NSRangeException
*** -[__NSArrayM objectAtIndex:]: index 0 beyond bounds for empty array
The crash is occurring in this ViewController:
https://gist.github.com/mustafa96m/21e762540c4798b0dd3853b2edb7867c
Thanks
This is going to be basically impossible to debug w/out a repro or sample project. What I can tell from the trace is that the crash happens inside UICollectionViewFlowLayout when updating its layout data cache. Weird issues like this might be from returning negative or NaN cell sizes. Without seeing all of the section controller code, or knowing which one is causing the issue, this will be pretty tough...
Ha 馃槄 So it looks like @benasher44 is seeing this in the PlanGrid codebase. (We don't use IGListKit.)
Sounds like this might be a bug in UIKit? @rnystrom time to send a love letter to Steve 馃拰
it's very similar!
0 CoreFoundation
___exceptionPreprocess
1 libobjc.A.dylib
_objc_exception_throw
2 CoreFoundation
-[__NSArrayM objectAtIndex:]
3 UIKit
-[UICollectionViewFlowLayout _frameForHeaderInSection:usingData:]
4 UIKit
-[UICollectionViewFlowLayout layoutAttributesForHeaderInSection:usingData:]
5 UIKit
-[UICollectionViewFlowLayout layoutAttributesForSupplementaryViewOfKind:atIndexPath:]
6 PlanGrid <redacted>
7 UIKit
-[UIScrollView(UIScrollViewInternal) _notifyDidScroll]
8 UIKit
-[UIScrollView setContentOffset:]
9 UIKit
-[UIScrollView(UIScrollViewInternal) _setContentOffset:animated:animationCurve:animationAdjustsForContentOffsetDelta:]
10 UIKit
-[UIScrollView(UIScrollViewInternal) _setContentOffset:animated:animationCurve:]
11 UIKit
-[UIScrollView setContentOffset:animated:]
12 UIKit
-[UICollectionView setContentOffset:animated:]
@benasher44 lmk if you solve! Seems my hunch is still some unexpected layout values messing up, but idk.
Sent with GitHawk
I'm coming across the same error which I think is related.
In my case I am loading in an image within a cell. On completion it dispatches an event that triggers:
self.collectionContext?.invalidateLayout(for: self) from within the SectionController to resize the cell with the correct dimensions.
However each time it crashes with
*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 2 beyond bounds for empty array'
Any suggestions would be hugely appreciated.
@stevejcox do you have a stack trace? Is it the same as above?
Thanks for the reply @rnystrom - I don't have the stack trace at the moment, I switched to using:
self.collectionContext?.performBatch(animated: false, updates: { (context) in
context.reload(self)
})
I do remember the stack trace was very similar to the above, though.
Hello again guys, happy thanksgiving to everyone 馃槃 . I finally could reproduce the issue on iPhone 4S simulator.
It's happening exactly in IGListAdapterUpdater.m:243
[delegate listAdapterUpdater:self
willCrashWithException:exception
fromObjects:fromObjects
toObjects:toObjects
updates:(id)self.applyingUpdateData];
using lldb to print objects :
Printing description of result:
<IGListIndexSetResult 0x7b07b2d0; 2 inserts; 0 deletes; 0 updates; 0 moves>
Printing description of result->_inserts:
<NSIndexSet: 0x7b080700>[number of indexes: 2 (in 1 ranges), indexes: (0-1)]
Printing description of result->_inserts->_indexSetFlags:
(struct (anonymous struct at /Applications/Xcode.app/Contents/./Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator11.1.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSIndexSet.h:33:5)) _indexSetFlags = {
_isEmpty = 0
_hasSingleRange = 1
_cacheValid = 0
_reservedArrayBinderController = 0
}
Printing description of result->_inserts->_internal:
(union (anonymous union at /Applications/Xcode.app/Contents/./Developer/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator11.1.sdk/System/Library/Frameworks/Foundation.framework/Headers/NSIndexSet.h:39:5)) _internal = {
_singleRange = (_range = location=0, length=2)
_multipleRanges = (_data = 0x00000000, _reserved = 0x00000002)
}
Printing description of result->_deletes:
<_NSCachedIndexSet: 0x79a792d0>(no indexes)
Printing description of result->_deletes:
(NSIndexSet) NSIndexSet = {
NSObject = {
isa = _NSCachedIndexSet
}
_indexSetFlags = {
_isEmpty = 1
_hasSingleRange = 1
_cacheValid = 0
_reservedArrayBinderController = 0
}
_internal = {
_singleRange = (_range = location=0, length=0)
_multipleRanges = (_data = 0x00000000, _reserved = 0x00000000)
}
}
Printing description of result->_updates:
<_NSCachedIndexSet: 0x79a792d0>(no indexes)
Printing description of result->_updates:
(NSIndexSet) NSIndexSet = {
NSObject = {
isa = _NSCachedIndexSet
}
_indexSetFlags = {
_isEmpty = 1
_hasSingleRange = 1
_cacheValid = 0
_reservedArrayBinderController = 0
}
_internal = {
_singleRange = (_range = location=0, length=0)
_multipleRanges = (_data = 0x00000000, _reserved = 0x00000000)
}
}
Printing description of result->_updates:
(NSIndexSet) NSIndexSet = {
NSObject = {
isa = _NSCachedIndexSet
}
_indexSetFlags = {
_isEmpty = 1
_hasSingleRange = 1
_cacheValid = 0
_reservedArrayBinderController = 0
}
_internal = {
_singleRange = (_range = location=0, length=0)
_multipleRanges = (_data = 0x00000000, _reserved = 0x00000000)
}
}
Printing description of self:
<IGListAdapterUpdater: 0x79fc8090>
Printing description of self:
(NSObject) NSObject = {
isa = IGListAdapterUpdater
}
Printing description of self->_fromObjects:
<nil>
Printing description of self->_fromObjects:
(NSObject) NSObject = <parent is NULL>
Printing description of self->_toObjects: ###### Here is the weird thing ########
<nil>
Printing description of self->_toObjects:
(NSObject) NSObject = <parent is NULL>
Printing description of fromObjects:
<__NSArray0 0x78641ab0>(
)
Printing description of toObjects: ###### Not Matching ########
<__NSArrayM 0x7b04b450>(
<IGSectionItem: 0x78728dc0>,
<IGSectionItem: 0x78704cc0>
)
Printing description of ((IGSectionItem *)0x78728dc0):
<IGSectionItem: 0x78728dc0>
Please tell me if you want to print something else for debugging,
First IGSectionItem is an empty section used for indention
#import "IndentSectionController.h"
@implementation IndentSectionController
-(NSInteger)numberOfItems{
return 1;
}
-(void)didUpdateToObject:(id)object{
}
-(void)didSelectItemAtIndex:(NSInteger)index{
}
-(CGSize)sizeForItemAtIndex:(NSInteger)index{
return CGSizeMake(self.collectionContext.containerSize.width, self.indentHeight);
}
-(UICollectionViewCell *)cellForItemAtIndex:(NSInteger)index{
UICollectionViewCell *cell = [self.collectionContext dequeueReusableCellOfClass:[UICollectionViewCell class] forSectionController:self atIndex:index];
[cell setBackgroundColor:[UIColor clearColor]];
return cell;
}
@end
2nd IGSectionItem is
#import "adjustableImageBlock.h"
#import "adjImageCell.h"
#import "UIColor+Colors.h"
#import <UIImageView+WebCache.h>
#import "RouteManager.h"
@implementation adjustableImageBlock
-(instancetype)init{
if (self = [super init]) {
self.inset = UIEdgeInsetsMake(5,5, 5, 5);
self.minimumLineSpacing = 5.f;
}
return self;
}
-(NSInteger)numberOfItems{
return [self.item.data count];
}
-(CGSize)sizeForItemAtIndex:(NSInteger)index
{
return CGSizeMake( self.collectionContext.containerSize.width / self.columns - 20.f,self.collectionContext.containerSize.width / self.columns - 20.f);
}
-(void)didUpdateToObject:(id)object{
self.item = object;
}
-(void)didSelectItemAtIndex:(NSInteger)index{
[[RouteManager sharedInstance] navigateWith:self.item.data[index]];
}
- (__kindof UICollectionViewCell *)cellForItemAtIndex:(NSInteger)index {
adjImageCell *cell = [self.collectionContext dequeueReusableCellWithNibName:@"adjImageCell" bundle:nil forSectionController:self atIndex:index];
[cell.adjImageView sd_setImageWithURL:[NSURL URLWithString:self.item.data[index][@"img"]] placeholderImage:[UIImage imageNamed:@"placeholder"] options:SDWebImageRefreshCached];
return cell;
}
@end
All sections are implementing @class IGSectionItem;
which is
#import <Foundation/Foundation.h>
#import <UIKit/UIKit.h>
#import <IGListKit.h>
@interface IGSectionItem : NSObject <IGListDiffable>
@property (nonatomic, copy) NSString *name;
@property (nonatomic, copy) NSDictionary *attributes;
@property (nonatomic,strong) id data;
@property (weak,nonatomic) UIViewController *controller;
- (instancetype)initWithName:(NSString *)name andData:(id) data controller:(UIViewController *)controller;
- (instancetype)initWithName:(NSString *)name andData:(id) data controller:(UIViewController *)controller attributes:(NSDictionary *)attributes;
@end
////// .m file
#import "IGSectionItem.h"
@implementation IGSectionItem
#pragma mark - Public
- (instancetype)initWithName:(NSString *)name andData:(id) data controller:(UIViewController *)controller {
if (self = [super init]) {
self.name = name;
self.controller = controller;
self.data = data;
}
return self;
}
- (instancetype)initWithName:(NSString *)name andData:(id) data controller:(UIViewController *)controller attributes:(NSDictionary *)attributes{
if (self = [super init]) {
self.name = name;
self.controller = controller;
self.data = data;
self.attributes = attributes;
}
return self;
}
#pragma mark - IGListDiffable
- (nonnull id<NSObject>)diffIdentifier {
return (self.data);
}
- (BOOL)isEqualToDiffableObject:(nullable id<IGListDiffable>)object {
BOOL s = object.diffIdentifier == self.data;
return s;
}
@end
Sorry for the late response and hope this helps.
Haven鈥檛 forgotten about this, just need some time to go through the code and traces! Let us know if you find any answers!
Sent with GitHawk
Sadly don't think there's enough evidence here that its an IGListKit issue. If you can repro in a demo project that'd be helpful for us. Closing due to inactivity.
Facing the same crash on iOS 9-10, on 11-12 everything work as expected, somebody solve it (except every time reloading)?
For you, from the future that came here asking why this is happening with your code: I my case, in one of the section controllers, i called collectionContext?.dequeueReusableCell(of:,for:,at:) inside the function sizeForItem(at index: Int). This cause this crash in my app, but only in some versions or devices. I hope this help you.
Most helpful comment
For you, from the future that came here asking why this is happening with your code: I my case, in one of the section controllers, i called
collectionContext?.dequeueReusableCell(of:,for:,at:)inside the functionsizeForItem(at index: Int). This cause this crash in my app, but only in some versions or devices. I hope this help you.