Search code examples
ioscatransaction

CATransaction completion block never fires


How come the completion block for this CATransaction never fires?

[CATransaction begin];
[CATransaction setCompletionBlock:^{
    // table animation has finished
    NSLog(@"why does this section never execute?");
}];
[self.tableView beginUpdates];
[self.tableView reloadRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:self.currentFeedItems.count inSection:0]] withRowAnimation:UITableViewRowAnimationFade];
[self.tableView endUpdates];
[CATransaction commit];

The tableview animation works, but the completion block is never executed. The Apple documentation says that the completion block is guaranteed to execute.


Solution

  • Oh boy, this was so obscure I'm actually amazed I found the problem.

    The cell that was being reloaded contains a UIActivityIndicatorView, which worked fine. When the cell reloads it implicitly redraws the table cell and a startAnimating call happens within that process in the table cell. Somehow that startAnimating call interferes with the CATransaction completion block.

    When I wrap the startAnimating call in a dispatch_async block, the problem goes away:

    dispatch_async(dispatch_get_main_queue(), ^{
        [self.loadingInd startAnimating];
    });