gsdios / SDAutoLayout

One line of code to implement automatic layout. 一行代码搞定自动布局!支持Cell和Tableview高度自适应,Label和ScrollView内容自适应,致力于做最简单易用的AutoLayout库。The most easy way for autoLayout. Based on runtime.
MIT License
5.9k stars 1.28k forks source link

动态添加数据后导致内存飙升闪退 #204

Closed lemon4ex closed 7 years ago

lemon4ex commented 7 years ago

问题很奇怪,进入控制器时,如果数据源为0,这个时候直接添加数据没有问题 如果此时将数据全部删除(使用deleteRowsAtIndexPaths删),这时候再重新添加数据,就会导致内存爆炸💥导致闪退,代码出在这里:

- (void)insertNewDataAtIndexPaths:(NSArray *)indexPaths
{
    NSMutableDictionary *sectionsdict = [NSMutableDictionary new];
    for (NSIndexPath *indexPath in indexPaths) {
        NSString *sectionkey = [@(indexPath.section) stringValue];
        if (![sectionsdict objectForKey:sectionkey]) {
            [sectionsdict setValue:[NSMutableArray new] forKey:sectionkey];
        }
        NSMutableArray *arr = sectionsdict[sectionkey];
        [arr addObject:indexPath];
    }
    for (NSString *sectionkey in sectionsdict.allKeys) {
        NSMutableArray *tempHeightCaches = [NSMutableArray new];
        NSMutableArray *tempFrameCaches = [NSMutableArray new];
        NSInteger section = [sectionkey integerValue];
        NSInteger rowCount = [self.modelTableview numberOfRowsInSection:section];
        if (rowCount <= 0) {
            continue;
        } else {
            for (int i = 0; i < rowCount; i++) {
                [tempHeightCaches addObject:[NSNull null]];
                [tempFrameCaches addObject:[NSNull null]];
            }
        }
。。。。。。。
}

rowCount此时为一个无穷大的数,而不是0,这导致下面添加了无穷多的[NSNull null],导致内存爆炸,闪退。rowCount为毛不是0,不得而知,系统bug?

添加数据的代码

[_setting.replyRules insertObject:rule atIndex:0];
[_tableView beginUpdates];
if (_setting.replyRules.count == 1) {
    [_tableView insertSections:[NSIndexSet indexSetWithIndex:2] withRowAnimation:UITableViewRowAnimationAutomatic];
}
[_tableView insertRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:0 inSection:2]] withRowAnimation:UITableViewRowAnimationAutomatic];
[_tableView endUpdates];

移除数据代码

- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSUInteger index = indexPath.row;
    [_setting.replyRules removeObjectAtIndex:index];
    [tableView beginUpdates];
    if (_setting.replyRules.count <= 0) {
        [_tableView deleteSections:[NSIndexSet indexSetWithIndex:2] withRowAnimation:UITableViewRowAnimationAutomatic];
    }
    [_tableView deleteRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:index inSection:2]] withRowAnimation:UITableViewRowAnimationAutomatic];
    [tableView endUpdates];
}
lemon4ex commented 7 years ago

解决方法: 替换 NSInteger rowCount = [self.modelTableview numberOfRowsInSection:section];NSInteger rowCount = [self.modelTableview.dataSource tableView:self.modelTableview numberOfRowsInSection:section]

应该是UIKit的bug吧