What is the meaning of the “no index path for table cell being reused” message in iOS 6/7?

前端 未结 14 2214
一整个雨季
一整个雨季 2020-11-27 15:12

Since starting to compile my app with iOS 6 (and since also iOS 7) I\'ve started seeing this message. I know that the way that UITableViews go about managing cells is diffe

相关标签:
14条回答
  • 2020-11-27 15:35

    This is obviously an old question, but hopefully this can help anyone who still gets this issue in iOS8+ because this is still the top question that comes up for this particular error message.

    I was using PINRemoteImage to async download an image to a UIImageView that was inside a custom UITableViewCell.

    In order to resize the row properly (dynamic height cells using auto-layout) once the image had loaded, I called:

    self.tableView beginUpdates;
    self.tableView endUpdates;
    

    I was then getting the "no index path for table cell being reused" message and the app was crashing. I had thought the PINRemoteImageManagerResult block was on the main thread, however it turns out that it wasn't - therefore ensuring that the begin/end updates was called on the main thread fixed the issue.

    dispatch_async(dispatch_get_main_queue(), ^(void){
                                [self.tableView beginUpdates];
                                [self.tableView endUpdates];
    });
    
    0 讨论(0)
  • 2020-11-27 15:43

    As an addition to my previous post (in which I mentioned that this was apparently a bug with UIKit), I was able to find a workaround for my particular case (in which the message was related to some strange visualisation glitches on the table).

    Apparently my custom cell's overridden -(void)setEditing:animated: was taking too long to return.

    My previous code was:

    - (void)setEditing:(BOOL)editing animated:(BOOL)animated
    {   
        [super setEditing:editing animated:animated];
        [self someAdditionalCode];
    }
    

    I was able to fix it by changing it to:

    - (void)setEditing:(BOOL)editing animated:(BOOL)animated
    {   
        [super setEditing:editing animated:animated];
    
        // DRM: we want to perform the actions from this block in the main thread, but
        // asynchronously to avoid excessive delays which were causing issues.
        //
        dispatch_async(dispatch_get_main_queue(), ^void()
        {
            [self someAdditionalCode];
        });
    }
    
    0 讨论(0)
  • 2020-11-27 15:43

    Maybe this helps someone: i once had this error while refreshing a single table view cell. I meant to do something like

    NSIndexPath *reloadRow = [NSIndexPath indexPathForRow:1 inSection:2];
    [self._mainTableView reloadRowsAtIndexPaths:@[reloadWebViewRow]
                               withRowAnimation:UITableViewRowAnimationFade];
    

    But accidentally, i typed

    NSIndexPath *reloadRow = [NSIndexPath indexPathForItem:1 inSection:2];
    

    Notice the difference of the two indexpaths: one is created with indexPathForItem (wrong), the other with indexPathForRow (correct). This all resulted in very strange behaviour of the tableView and the error message in the headline.

    0 讨论(0)
  • 2020-11-27 15:45

    Doing my endupdates after resignfirstresponder solved my problem (Have a UITextFIeld in my custom cell)

    -(void)textfieldEditDone
    {
    ....
    
        [textField resignFirstResponder];
        [self.tableView endUpdates];
    
    0 讨论(0)
  • 2020-11-27 15:48

    I'd return the contentView of the UITableViewCell instead of creating a wrapper.. having constraint-jabble fixed in storybord in mind

    return cell.contentView;
    
    0 讨论(0)
  • 2020-11-27 15:50

    It seems like my issue was triggered when I was trying to update the UI within a portion of the code that was a callback from a web call. I resolved by forcing UI updates to happen on the main thread. I used code like this.

    void runOnMainQueueWithoutDeadlocking(void (^block)(void)){
        if ([NSThread isMainThread])
        {
            block();
        }
        else
        {
            dispatch_sync(dispatch_get_main_queue(), block);
        }
    }
    

    I call it as follows inside of the success block of my background web call.

    runOnMainQueueWithoutDeadlocking(^{
        [self.tableView beginUpdates];
        [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:1] withRowAnimation:UITableViewRowAnimationAutomatic];
        [self.tableView reloadSections:[NSIndexSet indexSetWithIndex:2] withRowAnimation:UITableViewRowAnimationAutomatic];
        [self.tableView endUpdates];
    });
    
    0 讨论(0)
提交回复
热议问题