IOS 7 TableView奇怪的循环

时间:2017-07-14 11:36:32

标签: ios objective-c iphone uitableview ios7

我在iPhone 4设备上的iOS7上遇到这个奇怪的问题,不确定是否会在较新的版本或设备中发生这种情况。我目前无法在目前使用iOS 11测试版的iPhone 6中复制此问题。

I have a Tableview with a NSFetchecResult as the table datasource.

The problem appears when I scroll the table this loop randomly happens.

this is the log:
2017-07-14 10:13:21.158 APP[28317:60b] cellForRowAtIndexPath <NSIndexPath: 0x18a58970> {length = 2, path = 3 - 0}
2017-07-14 10:13:21.223 APP[28317:60b] viewForHeaderInSection:4  
2017-07-14 10:13:21.241 APP[28317:60b] cellForRowAtIndexPath:<NSIndexPath: 0x18f35450> {length = 2, path = 4 - 0}
2017-07-14 10:13:21.293 APP[28317:60b] scrollViewDidEndDragging -> notScrolling  
2017-07-14 10:13:21.318 APP[28317:60b] scrollViewDidScroll -> isScrolling  
2017-07-14 10:13:21.335 APP[28317:60b] viewForHeaderInSection:5  
2017-07-14 10:13:21.354 APP[28317:60b] cellForRowAtIndexPath:
 <NSIndexPath: 0x18f34910> {length = 2, path = 5 - 0}  
2017-07-14 10:13:21.404 APP[28317:60b] viewForHeaderInSection:6  
2017-07-14 10:13:21.420 APP[28317:60b] cellForRowAtIndexPath:<NSIndexPath: 0x18f50cf0> {length = 2, path = 6 - 0}  
2017-07-14 10:13:21.825 APP[28317:60b] scrollViewDidEndDecelerating -> >notScrolling  
2017-07-14 10:13:21.855 APP[28317:60b] scrollViewWillBeginDragging -> isScrolling  
2017-07-14 10:13:21.887 APP[28317:60b] cellForRowAtIndexPath:<NSIndexPath: 0x1763b350> {length = 2, path = 2 - 0}  
2017-07-14 10:13:21.920 APP[28317:60b] viewForHeaderInSection:2  
2017-07-14 10:13:21.958 APP[28317:60b] cellForRowAtIndexPath:<NSIndexPath: 0x18acb2b0> {length = 2, path = 1 - 0}  
2017-07-14 10:13:21.992 APP[28317:60b] cellForRowAtIndexPath:<NSIndexPath: 0x18a2e640> {length = 2, path = 0 - 0}  
2017-07-14 10:13:22.054 APP[28317:60b] viewForHeaderInSection:0  
2017-07-14 10:13:22.070 APP[28317:60b] viewForHeaderInSection:1  
2017-07-14 10:13:22.092 APP[28317:60b] numberOfSectionsInTableView  
2017-07-14 10:13:22.100 APP[28317:60b] numberOfSectionsInTableView -> 7  
2017-07-14 10:13:22.105 APP[28317:60b] numberOfRowsInSection:6 -> 1  
2017-07-14 10:13:22.108 APP[28317:60b] numberOfRowsInSection:0 -> 1  
2017-07-14 10:13:22.117 APP[28317:60b] numberOfRowsInSection:1 -> 1  
2017-07-14 10:13:22.136 APP[28317:60b] numberOfRowsInSection:2 -> 1  
2017-07-14 10:13:22.140 APP[28317:60b] numberOfRowsInSection:3 -> 1  
2017-07-14 10:13:22.144 APP[28317:60b] numberOfRowsInSection:4 -> 1  
2017-07-14 10:13:22.154 APP[28317:60b] numberOfRowsInSection:5 -> 1  
2017-07-14 10:13:22.275 APP[28317:60b] numberOfSectionsInTableView  
2017-07-14 10:13:22.284 APP[28317:60b] numberOfSectionsInTableView -> 7  
2017-07-14 10:13:22.288 APP[28317:60b] numberOfRowsInSection:6 -> 1  
2017-07-14 10:13:22.291 APP[28317:60b] numberOfRowsInSection:0 -> 1  
2017-07-14 10:13:22.298 APP[28317:60b] numberOfRowsInSection:1 -> 1  
2017-07-14 10:13:22.303 APP[28317:60b] numberOfRowsInSection:2 -> 1  
2017-07-14 10:13:22.306 APP[28317:60b] numberOfRowsInSection:3 -> 1  
2017-07-14 10:13:22.309 APP[28317:60b] numberOfRowsInSection:4 -> 1  
2017-07-14 10:13:22.317 APP[28317:60b] numberOfRowsInSection:5 -> 1  
2017-07-14 10:13:22.536 APP[28317:60b] numberOfSectionsInTableView  
2017-07-14 10:13:22.540 APP[28317:60b] numberOfSectionsInTableView -> 7  
2017-07-14 10:13:22.543 APP[28317:60b] numberOfRowsInSection:6 -> 1  
2017-07-14 10:13:22.565 APP[28317:60b] numberOfRowsInSection:0 -> 1  
2017-07-14 10:13:22.569 APP[28317:60b] numberOfRowsInSection:1 -> 1  
2017-07-14 10:13:22.572 APP[28317:60b] numberOfRowsInSection:2 -> 1  
2017-07-14 10:13:22.576 APP[28317:60b] numberOfRowsInSection:3 -> 1  
2017-07-14 10:13:22.585 APP[28317:60b] numberOfRowsInSection:4 -> 1  
2017-07-14 10:13:22.589 APP[28317:60b] numberOfRowsInSection:5 -> 1  
2017-07-14 10:13:22.737 APP[28317:60b] numberOfSectionsInTableView  
2017-07-14 10:13:22.741 APP[28317:60b] numberOfSectionsInTableView -> 7  
2017-07-14 10:13:22.748 APP[28317:60b] numberOfRowsInSection:6 -> 1  
2017-07-14 10:13:22.752 APP[28317:60b] numberOfRowsInSection:0 -> 1  
2017-07-14 10:13:22.756 APP[28317:60b] numberOfRowsInSection:1 -> 1  
2017-07-14 10:13:22.759 APP[28317:60b] numberOfRowsInSection:2 -> 1  
2017-07-14 10:13:22.768 APP[28317:60b] numberOfRowsInSection:3 -> 1  
2017-07-14 10:13:22.772 APP[28317:60b] numberOfRowsInSection:4 -> 1  
2017-07-14 10:13:22.775 APP[28317:60b] numberOfRowsInSection:5 -> 1  
2017-07-14 10:13:22.838 APP[28317:60b] numberOfSectionsInTableView

看起来tableview开始重新加载数据并在加载节标题的视图时进入循环。

这是我的tableview委托和数据源的代码: 在这里,我准备我的数据源

    -(void) loadDBData
    {
        NSLog(@"loadDBData");

        NSString *entityName = nil;

        switch (_tableView.tag) {
            case 1:
                entityName =  NSStringFromClass([Vehicle class]);
                break;

            case 2:
                entityName =  NSStringFromClass([Driver class]);
                break;

            default:
                entityName =  NSStringFromClass([Zone class]);
                break;
        }


        NSFetchRequest *fetchRequest = [[NSFetchRequest alloc] initWithEntityName: entityName];

        // Set the batch size to a suitable number.
        //    [fetchRequest setFetchBatchSize:5];

        NSSortDescriptor *groupSort = [[NSSortDescriptor alloc] initWithKey:@"group.name" ascending:YES];
        NSSortDescriptor *nameSort = nil;

        switch (_tableView.tag) {
            case 1:
                nameSort = [[NSSortDescriptor alloc] initWithKey:@"vehicleDescription" ascending:YES];
                break;

            default:
                nameSort = [[NSSortDescriptor alloc] initWithKey:@"name" ascending:YES];
                break;
        }
        NSSortDescriptor *groupSortID = [[NSSortDescriptor alloc] initWithKey:@"group.id_group" ascending:YES];

        fetchRequest.sortDescriptors = @[groupSort, groupSortID, nameSort];

        self.fechedResultController = [[NSFetchedResultsController alloc] initWithFetchRequest:fetchRequest managedObjectContext:[DBController getDBController].managedObjectContext sectionNameKeyPath:@"group" cacheName:nil];

        [self.fechedResultController setDelegate:self];

        NSError *fetchingError = nil;
        if([self.fechedResultController performFetch:&fetchingError])
        {
            NSLog(@"Successfully fetched.");
        }
        else
            NSLog(@"Failed to fetch.");

    }

这是我在coredata更改时管理的

    #pragma mark - NSFetchResultsControllerDelegate
    -(void)controllerWillChangeContent:(NSFetchedResultsController *)controller
    {

        if(!_isScrolling)
        {
            NSLog(@"TableView Begins Update");
            [self.tableView beginUpdates];
        }
        else
            _tableViewNeedsToUpdate = YES;
    }

    -(void)controller:(NSFetchedResultsController *)controller didChangeObject:(id)anObject atIndexPath:(NSIndexPath *)indexPath forChangeType:(NSFetchedResultsChangeType)type newIndexPath:(NSIndexPath *)newIndexPath
    {
        if(!_isScrolling)
        {
            switch(type) {

                case NSFetchedResultsChangeInsert:
                    NSLog(@"didChangeObject -> NSFetchedResultsChangeInsert");
                    [self.tableView insertRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
                    break;

                case NSFetchedResultsChangeDelete:
                    NSLog(@"didChangeObject -> NSFetchedResultsChangeDelete");
                    [self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
                    break;

                case NSFetchedResultsChangeUpdate:
                    NSLog(@"didChangeObject -> NSFetchedResultsChangeUpdate");
                    [self configureCell:[self.tableView cellForRowAtIndexPath:indexPath] atIndexPath:indexPath];
                    break;

                case NSFetchedResultsChangeMove:
                    NSLog(@"didChangeObject -> NSFetchedResultsChangeMove");

                    [self.tableView deleteRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationFade];
                    [self.tableView insertRowsAtIndexPaths:[NSArray arrayWithObject:newIndexPath] withRowAnimation:UITableViewRowAnimationFade];
                    break;
            }
        }
    }

    -(void)controller:(NSFetchedResultsController *)controller didChangeSection:(id<NSFetchedResultsSectionInfo>)sectionInfo atIndex:(NSUInteger)sectionIndex forChangeType:(NSFetchedResultsChangeType)type
    {
        if(!_isScrolling)
        {
            switch(type) {

                case NSFetchedResultsChangeInsert:
                    NSLog(@"didChangeSection -> NSFetchedResultsChangeInsert");
                    [self.tableView insertSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
                    break;

                case NSFetchedResultsChangeDelete:
                    NSLog(@"didChangeSection -> NSFetchedResultsChangeDelete");
                    [self.tableView deleteSections:[NSIndexSet indexSetWithIndex:sectionIndex] withRowAnimation:UITableViewRowAnimationFade];
                    break;

                    default:
                    break;
            }
        }

    }

    -(void)controllerDidChangeContent:(NSFetchedResultsController *)controller
    {
        if(!_isScrolling)
        {
            [self.tableView endUpdates];
            NSLog(@"TableView Ends Update");
        }
    }

这就是我在做tableview的事情

    #pragma mark - UITableView DataSource & Delegate
    -(NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    {
        NSLog(@"numberOfSectionsInTableView");

        NSInteger nSections = 0;


        id  sectionInfo = [self.fechedResultController sections] ;
        nSections = [sectionInfo count];

        NSLog(@"numberOfSectionsInTableView -> %li", (long)nSections);

        return nSections;
    }

    -(UIView *)tableView:(UITableView *)tableView viewForHeaderInSection:(NSInteger)section
    {
        NSLog(@"viewForHeaderInSection:%li",(long)section);



        id <NSFetchedResultsSectionInfo> sectionInfo = [[self.fechedResultController sections] objectAtIndex:section];
        if(sectionInfo)
        {
            NSString *sectionName = [[[[sectionInfo objects] firstObject] group]name];

            UIView *header = [[UIView alloc] initWithFrame:CGRectMake(0, 0, tableView.frame.size.width, 28)];
            [header setBackgroundColor:[UIColor lightGrayColor]];
            UILabel *headerText = [[UILabel alloc] initWithFrame: CGRectMake(18, 4, tableView.frame.size.width - (18*2), 20)];
            [headerText setTextColor:[UIColor blackColor]];
            [headerText setFont:[UIFont fontWithName:@"Arial-BoldMT" size:20]];
            [headerText setText: sectionName];

            [header addSubview:headerText];

            return header;

        }
        else
            return nil;



    }

    -(NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
    //    NSLog(@"numberOfRowsInSection:%i",section);

        NSInteger nRows = 0;


        id<NSFetchedResultsSectionInfo> sectionInfo = self.fechedResultController.sections[section];

        nRows = sectionInfo.numberOfObjects;

        NSLog(@"numberOfRowsInSection:%li -> %li",(long)section, (long)nRows);

        return nRows;

    }

    -(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        NSLog(@"cellForRowAtIndexPath:%@",[indexPath description]);

    //    NSInteger section = indexPath.section;
    //    NSInteger row = indexPath.row;


        FilterListTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"Cell"];

        if (cell == nil)
            cell = [[FilterListTableViewCell alloc] init];


        [cell setMyDelegate:self];

        id dataObject = [self.fechedResultController objectAtIndexPath:indexPath];
        [cell setCellForObject: dataObject];

        return cell;
    }


    - (void)configureCell:(FilterListTableViewCell *)cell atIndexPath:(NSIndexPath *)indexPath
    {
        NSLog(@"configureCell:atIndexPath%@",[indexPath description]);
        id dataObject = [self.fechedResultController objectAtIndexPath:indexPath];
        [cell setCellForObject: dataObject];

    }

这是scroolDelegate的代码。我使用它来保证只有在没有滚动动画时才更新tabledata。 我在尝试识别并纠正问题时添加了这个,因为我认为滚动时表更新导致了问题。但仍然在循环。

#pragma mark - UIScroolView Delegate
-(void)scrollViewWillBeginDragging:(UIScrollView *)scrollView
{
    if(!_isScrolling)
    {
        _isScrolling = YES;

        NSLog(@"scrollViewWillBeginDragging -> isScrolling");
    }
}

- (void)scrollViewDidScroll:(UIScrollView *)sender
{
    if(!_isScrolling)
    {
        _isScrolling = YES;

        NSLog(@"scrollViewDidScroll -> isScrolling");

    }
}

-(void)scrollViewDidEndDragging:(UIScrollView *)scrollView willDecelerate:(BOOL)decelerate
{
    if(_isScrolling)
    {
        _isScrolling = NO;
        if (_tableViewNeedsToUpdate) {
            [self.tableView reloadData];
            _tableViewNeedsToUpdate = NO;
        }

        NSLog(@"scrollViewDidEndDragging -> notScrolling");

    }
}

-(void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
    if(_isScrolling)
    {
        _isScrolling = NO;
        if (_tableViewNeedsToUpdate) {
            [self.tableView reloadData];
            _tableViewNeedsToUpdate = NO;

        }
        NSLog(@"scrollViewDidEndDecelerating -> notScrolling");

    }
}

0 个答案:

没有答案