iOS【UICollectionView:reloadData与reloadSections冲突问题】


/*******
TestReload[32490:289811] ------after---reload
TestReload[32490:289811] -----------numberOfSectionsInCollectionView

TestReload[32490:289811] *** Assertion failure in -[UICollectionView _endItemAnimationsWithInvalidationContext:tentativelyForReordering:animator:], /BuildRoot/Library/Caches/com.apple.xbs/Sources/UIKitCore_Sim/UIKit-3698.84.15/UICollectionView.m:6120

TestReload[32490:289811] *** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'Invalid update: invalid number of items in section 0. The number of items contained in an existing section after the update (1) must be equal to the number of items contained in that section before the update (2), plus or minus the number of items inserted or deleted from that section (0 inserted, 0 deleted) and plus or minus the number of items moved into or out of that section (0 moved in, 0 moved out).'
*** First throw call stack:
(
0 CoreFoundation 0x0000000102b8629b __exceptionPreprocess + 331
1 libobjc.A.dylib 0x0000000102122735 objc_exception_throw + 48
2 CoreFoundation 0x0000000102b86022 +[NSException raise:format:arguments:] + 98
3 Foundation 0x0000000101b26b47 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 194
4 UIKitCore 0x00000001054c07cf -[UICollectionView _endItemAnimationsWithInvalidationContext:tentativelyForReordering:animator:] + 16010
5 UIKitCore 0x00000001054bc09f -[UICollectionView _updateSections:updateAction:] + 431
6 UIKitCore 0x00000001054bc1b4 -[UICollectionView reloadSections:] + 62
7 TestReload 0x000000010180119c __29-[ViewController viewDidLoad]_block_invoke + 204
8 libdispatch.dylib 0x000000010447663e _dispatch_client_callout + 8
9 libdispatch.dylib 0x0000000104479589 _dispatch_continuation_pop + 565
10 libdispatch.dylib 0x000000010448b89f _dispatch_source_invoke + 2211
11 libdispatch.dylib 0x0000000104483800 _dispatch_main_queue_callback_4CF + 1071
12 CoreFoundation 0x0000000102ae97f9 CFRUNLOOP_IS_SERVICING_THE_MAIN_DISPATCH_QUEUE + 9
13 CoreFoundation 0x0000000102ae3e86 __CFRunLoopRun + 2342
14 CoreFoundation 0x0000000102ae3221 CFRunLoopRunSpecific + 625
15 GraphicsServices 0x000000010b1511dd GSEventRunModal + 62
16 UIKitCore 0x00000001053fd115 UIApplicationMain + 140
17 TestReload 0x00000001018023a0 main + 112
18 libdyld.dylib 0x00000001044ec551 start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException
*/


代码块

#import "ViewController.h"

@interface ViewController ()

@property (nonatomic, strong) UICollectionView   *collectView;
@property (nonatomic, strong) NSMutableArray     *testArray;
@property (nonatomic, strong) NSMutableArray     *testArray2;

@property (nonatomic, strong) NSMutableArray     *testArray3;

@property (nonatomic, assign) BOOL               has3Group;

@end

@implementation ViewController

- (NSMutableArray *)testArray {
    if (!_testArray) {
        _testArray = [[NSMutableArray alloc] init];
    }
    return _testArray;
}

- (NSMutableArray *)testArray2 {
    if (!_testArray2) {
        _testArray2 = [[NSMutableArray alloc] init];
    }
    return _testArray2;
}

- (NSMutableArray *)testArray3 {
    if (!_testArray3) {
        _testArray3 = [[NSMutableArray alloc] init];
    }
    return _testArray3;
}

- (UICollectionView *)collectView {
    if (!_collectView) {
        UICollectionViewFlowLayout *layout = [[UICollectionViewFlowLayout alloc] init];
        _collectView = [[UICollectionView alloc] initWithFrame:self.view.bounds collectionViewLayout:layout];
        _collectView.delegate = self;
        _collectView.dataSource = self;
        [_collectView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"tewCell"];
    }
    return _collectView;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //测试组数 默认2组
//    self.has3Group = YES;
    
    NSLog(@"------section组1:源-------");
    [self.testArray addObjectsFromArray:@[@"00000-0",@"0000001"]];
    NSLog(@"------section组2:源-------");
    [self.testArray2 addObjectsFromArray:@[@"11111-0",@"11111-1"]];
    [self.testArray3 addObjectsFromArray:@[@"22222-0",@"22222-1"]];
    [self.view addSubview:self.self.collectView];
    
    self.collectView.backgroundColor = [UIColor lightGrayColor];
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        
        NSLog(@"------after---reload");
        //===== 测试1 修改第一组数据源,刷新第二组 崩溃 ======//
        [self.testArray removeLastObject];
        [self.collectView reloadSections:[NSIndexSet indexSetWithIndex:1]];
        

        //===== 测试2 修改第二组数据源,刷新第一组 崩溃 ======//
//        //[self.testArray removeLastObject];
//        [self.testArray2 removeLastObject];
//        [self.collectView reloadSections:[NSIndexSet indexSetWithIndex:0]];
//
        //===== 测试3 修改第一组数据源,刷新一、二组 没问题 ======//
//        [self.testArray removeLastObject];
//        [self.collectView reloadSections:[NSIndexSet indexSetWithIndex:0]];
//        [self.collectView reloadSections:[NSIndexSet indexSetWithIndex:1]];
//
//        //===== 测试4 修改第一组数据源,刷新二、一组 崩溃 ======//
//        [self.testArray removeLastObject];
//        [self.collectView reloadSections:[NSIndexSet indexSetWithIndex:1]];
//        [self.collectView reloadSections:[NSIndexSet indexSetWithIndex:0]];
        
        
        //===== 测试5 修改第二组数据源,刷新二、一组 没问题 ======//
//        [self.testArray2 removeLastObject];
//        [self.collectView reloadSections:[NSIndexSet indexSetWithIndex:1]];
//        [self.collectView reloadSections:[NSIndexSet indexSetWithIndex:0]];
        
        //===== 测试6 修改第二组数据源,刷新一、二组 崩溃 ======//
//        [self.testArray2 removeLastObject];
//        [self.collectView reloadSections:[NSIndexSet indexSetWithIndex:0]];
//        [self.collectView reloadSections:[NSIndexSet indexSetWithIndex:1]];
        
        //===== 测试7 修改第一、二组数据源,刷新一组 或 二组 崩溃 ======//
//        [self.testArray removeLastObject];
//        [self.testArray2 removeLastObject];
//        [self.collectView reloadSections:[NSIndexSet indexSetWithIndex:0]];
//        [self.collectView reloadSections:[NSIndexSet indexSetWithIndex:1]];
        
        //===== 测试8 修改第一刷新一、修改二刷新二,都执行 ======//
//        [self.testArray2 removeLastObject];
//        [self.collectView reloadSections:[NSIndexSet indexSetWithIndex:1]];
//         [self.testArray removeLastObject];
//        [self.collectView reloadSections:[NSIndexSet indexSetWithIndex:0]];
        

//        [self testReloadOrSection_0];

//        [self testReloadOrSection_1];
//
//        [self testReloadOrSection_2];
//
//        [self testReloadOrSection_3];
//
//        [self testReloadOrSection_4];

//        [self testReloadOrSection_3Groub5];
        
//        [self testReloadOrSection_3Group6];
    });
}
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath {
    UICollectionViewCell *cell = [collectionView dequeueReusableCellWithReuseIdentifier:@"tewCell" forIndexPath:indexPath];
    cell.backgroundColor = [UIColor greenColor];
    
    NSArray *tempArr = indexPath.section == 0 ?  self.testArray : (indexPath.section == 1 ? self.testArray2 : self.testArray3);
    NSLog(@"\n-----sectin: indx: %li, %ld  %@",indexPath.section,(long)indexPath.row,tempArr);
    return cell;
}
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView {
    NSLog(@"-----------numberOfSectionsInCollectionView");
    return self.has3Group ? 3 : 2;
}
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section {
    if (section == 0) {
        return self.testArray.count;
    } else if (section == 1) {
        return self.testArray2.count;
    }
    return self.testArray3.count;
}


- (void)testReloadOrSection_0 {
    
    //===== 测试9 修改第一刷新一、修改二刷新表, ======//
    [self.testArray removeLastObject];
    //执行有效
    [self.collectView reloadSections:[NSIndexSet indexSetWithIndex:0]];
    [self.testArray2 removeLastObject];
    //不执行
    [self.collectView reloadData];
    NSLog(@"self.testArray2: %@",self.testArray2);
    
    /**
    结果:
    2018-10-27 16:46:35.746080+0800 TestReload[31767:268106] ------after---reload
    2018-10-27 16:46:35.747224+0800 TestReload[31767:268106]
    -----sectin: indx: 0, 0  (
                              "00000-0"
                              )
    2018-10-27 16:46:35.748565+0800 TestReload[31767:268106] self.testArray2: (
                                                                               "11111-0"
                                                                               )
     */
}

- (void)testReloadOrSection_1 {
    
    //===== 测试10 修改第一刷新表,在修改二、(结果:数据一、二都会刷) ======//
    [self.testArray2 removeLastObject];
    [self.collectView reloadData];
    [self.testArray removeLastObject];

    //延迟就不会刷
//    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(0.5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
//        [self.testArray removeLastObject];
//    });
    
    /**
     结果:
     2018-10-27 16:30:23.917433+0800 TestReload[31482:259201] ------after---reload
     2018-10-27 16:30:23.918204+0800 TestReload[31482:259201]
     -----sectin: indx: 0, 0  (
     "00000-0"
     )
     2018-10-27 16:30:23.918396+0800 TestReload[31482:259201]
     -----sectin: indx: 1, 0  (
     "11111-0"
     )
     */
}

- (void)testReloadOrSection_2 {
    
    //===== 测试11 修改第一刷新表,在修改二、(结果:数据一、二都会刷) ======//
    [self.testArray2 removeLastObject];
    [self.collectView reloadData];
    [self.testArray removeLastObject];
    [self.collectView reloadSections:[NSIndexSet indexSetWithIndex:0]];
    
    /**
     结果:【 先刷 0 ,后刷 1 】
     -----sectin: indx: 0, 0  (
     "00000-0"
     )
     2018-10-27 16:31:39.886629+0800 TestReload[31520:260372]
     -----sectin: indx: 1, 0  (
     "11111-0"
     )
     */
}

- (void)testReloadOrSection_3 {
    
    //===== 测试12 修改第一刷新表,在修改二、(结果:数据一、二都会刷) ======//
    [self.testArray2 removeLastObject];
    [self.collectView reloadData];
    [self.testArray removeLastObject];
    //【 先刷 1 ,后刷 0 】
    [self.collectView reloadSections:[NSIndexSet indexSetWithIndex:1]];
    
    /**
     结果: 【 先刷 1 ,后刷 0 】
     2018-10-27 16:33:07.055397+0800 TestReload[31553:261296] ------after---reload
     2018-10-27 16:33:07.056510+0800 TestReload[31553:261296]
     -----sectin: indx: 1, 0  (
     "11111-0"
     )
     2018-10-27 16:33:07.056817+0800 TestReload[31553:261296]
     -----sectin: indx: 0, 0  (
     "00000-0"
     )
     */
}

- (void)testReloadOrSection_4 {
    
    //===== 测试12 修改第一刷新表,在修改二、(结果:数据一、二都会刷 没问题) ======//
    [self.testArray2 removeLastObject];
    [self.collectView reloadData];
    [self.testArray removeLastObject];
    [self.collectView reloadData];
    
    /**
    结果:
    2018-10-27 16:42:33.134940+0800 TestReload[31694:265878] ------after---reload
    2018-10-27 16:42:33.135664+0800 TestReload[31694:265878]
    -----sectin: indx: 0, 0  (
                              "00000-0"
                              )
    2018-10-27 16:42:33.135846+0800 TestReload[31694:265878]
    -----sectin: indx: 1, 0  (
                              "11111-0"
                              )
     */
}


- (void)testReloadOrSection_3Groub5 {
    // 3组
    if (!self.has3Group) {
        return;
    }
    //===== 测试12 修改第一刷新表,在修改二、(结果:数据一、二都会刷) ======//
    [self.testArray2 removeLastObject];
    [self.collectView reloadData];
    [self.testArray removeLastObject];
    //【 先刷 1 ,后刷 0 】
    [self.collectView reloadSections:[NSIndexSet indexSetWithIndex:1]];
    [self.collectView reloadSections:[NSIndexSet indexSetWithIndex:2]];
    
    /***
    结果:
    018-10-27 16:56:46.212766+0800 TestReload[31928:273289] ------after---reload
    2018-10-27 16:56:46.214051+0800 TestReload[31928:273289]
    -----sectin: indx: 1, 0  (
                              "11111-0"
                              )
    2018-10-27 16:56:46.214354+0800 TestReload[31928:273289]
    -----sectin: indx: 0, 0  (
                              "00000-0"
                              )
    2018-10-27 16:56:46.214606+0800 TestReload[31928:273289]
    -----sectin: indx: 2, 0  (
                              "22222-0",
                              "22222-1"
                              )
    2018-10-27 16:56:46.214814+0800 TestReload[31928:273289]
    -----sectin: indx: 2, 1  (
                              "22222-0",
                              "22222-1"
                              )
    2018-10-27 16:56:46.216255+0800 TestReload[31928:273289]
    -----sectin: indx: 2, 0  (
                              "22222-0",
                              "22222-1"
                              )
    2018-10-27 16:56:46.216513+0800 TestReload[31928:273289]
    -----sectin: indx: 2, 1  (
                              "22222-0",
                              "22222-1"
                              )

    */
}


- (void)testReloadOrSection_3Group6 {
    // 3组
    if (!self.has3Group) {
        return;
    }
    //===== 测试12 修改第一刷新表,在修改二、(结果:数据一、二都会刷) ======//
    [self.testArray2 removeLastObject];
    [self.collectView reloadData];
    [self.testArray removeLastObject];
    // 注意结果顺序 可以自己换换试试 结果有点奇怪
    [self.collectView reloadSections:[NSIndexSet indexSetWithIndex:2]];
    [self.collectView reloadSections:[NSIndexSet indexSetWithIndex:0]];
    
    /***
    结果:注意结果顺序
    2018-10-27 17:09:19.441771+0800 TestReload[32182:280787] ------after---reload
    2018-10-27 17:09:19.442226+0800 TestReload[32182:280787] -----------numberOfSectionsInCollectionView
    2018-10-27 17:09:19.442572+0800 TestReload[32182:280787] -----------numberOfSectionsInCollectionView
    2018-10-27 17:09:19.443159+0800 TestReload[32182:280787]
    -----sectin: indx: 2, 0  (
                              "22222-0",
                              "22222-1"
                              )
    2018-10-27 17:09:19.443402+0800 TestReload[32182:280787]
    -----sectin: indx: 2, 1  (
                              "22222-0",
                              "22222-1"
                              )
    2018-10-27 17:09:19.443630+0800 TestReload[32182:280787]
    -----sectin: indx: 0, 0  (
                              "00000-0"
                              )
    2018-10-27 17:09:19.443849+0800 TestReload[32182:280787]
    -----sectin: indx: 1, 0  (
                              "11111-0"
                              )
    2018-10-27 17:09:19.444969+0800 TestReload[32182:280787] -----------numberOfSectionsInCollectionView
    2018-10-27 17:09:19.445387+0800 TestReload[32182:280787]
    -----sectin: indx: 0, 0  (
                              "00000-0"
                              )
     */
    
    
    //[self.collectView reloadSections:[NSIndexSet indexSetWithIndex:2]];
    //[self.collectView reloadSections:[NSIndexSet indexSetWithIndex:1]];
    /**
    结果:
    2018-10-27 17:14:47.485862+0800 TestReload[32264:283424] ------after---reload
    2018-10-27 17:14:47.486340+0800 TestReload[32264:283424] -----------numberOfSectionsInCollectionView
    2018-10-27 17:14:47.486698+0800 TestReload[32264:283424] -----------numberOfSectionsInCollectionView
    2018-10-27 17:14:47.487274+0800 TestReload[32264:283424]
    -----sectin: indx: 2, 0  (
                              "22222-0",
                              "22222-1"
                              )
    2018-10-27 17:14:47.487533+0800 TestReload[32264:283424]
    -----sectin: indx: 2, 1  (
                              "22222-0",
                              "22222-1"
                              )
    2018-10-27 17:14:47.487760+0800 TestReload[32264:283424]
    -----sectin: indx: 0, 0  (
                              "00000-0"
                              )
    2018-10-27 17:14:47.487976+0800 TestReload[32264:283424]
    -----sectin: indx: 1, 0  (
                              "11111-0"
                              )
    2018-10-27 17:14:47.489072+0800 TestReload[32264:283424] -----------numberOfSectionsInCollectionView
    2018-10-27 17:14:47.489533+0800 TestReload[32264:283424]
    -----sectin: indx: 1, 0  (
                              "11111-0"
                              )
     */
}
@end
附加:

*** Assertion failure in -[UICollectionView _endItemAnimationsWithInvalidationContext:tentativelyForReordering:]

func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
        collectionView.performBatchUpdates({ () -> Void in
                collectionView.deleteItemsAtIndexPaths([indexPath])
            }) { (finish) -> Void in
        }
    }

原因:执行完performBatchUpdates操作之后,collection view会自动reloadData,
调用numberOfItemsInSection等方法重新布局,
这时就会出现数据越界等情况,
所以要在performBatchUpdates的block中更新numberOfItemsInSection的个数:

func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
        collectionView.performBatchUpdates({ () -> Void in
                collectionView.deleteItemsAtIndexPaths([indexPath])
                // 该函数的作用是删除对应的模型数据
               self.removeImageWithIndex(indexPath.row)
            }) { (finish) -> Void in
        }
    }

你可能感兴趣的:(iOS【UICollectionView:reloadData与reloadSections冲突问题】)