scrollPosition时崩溃

scrollPosition时崩溃

本文介绍了调用selectRowAtIndexPath:animated:scrollPosition时崩溃:的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有以下方法为当前中心视图控制器选择行:

I have the following method that selects the row for the current center view controller:

- (void)_updateSelection
{
    [self.tableView reloadData];

    [_viewControllers enumerateKeysAndObjectsUsingBlock:^(NSString *path, UIViewController *viewController, BOOL *stop) {
        if (viewController == self.revealSideViewController.rootViewController) {
            NSInteger row = [self indexOfPath:path];
            if (row != NSNotFound && row < [self.tableView numberOfRowsInSection:0]) {
                [self.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:row inSection:0] animated:NO scrollPosition:UITableViewScrollPositionNone];
            }

            *stop = YES;
        }
    }];
}

如您所见,我进行了几项检查以确保所有内容均有效。根据表格视图,该行位于该部分的范围内。而且在大多数情况下,这很好。由于在调用 reloadData 时,表视图会不断失去选择,因此在需要进行更改时会调用此视图。我也在 viewWillAppear:中称呼它。

As you can see, I have several checks to make sure everything is valid. According to the table view, the row is within the bounds of the section. And most of the time, this works just fine. Because the table view keeps loosing its selection when reloadData is called, I call this when I need to make changes. I also call it in viewWillAppear:. Here is where it occasionally crashes.

崩溃的输出是:

*** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 2 beyond bounds [0 .. 0]'
*** First throw call stack:
(
    0   CoreFoundation                      0x041415e4 __exceptionPreprocess + 180
    1   libobjc.A.dylib                     0x03ec48b6 objc_exception_throw + 44
    2   CoreFoundation                      0x040e24e6 -[__NSArrayM objectAtIndex:] + 246
    3   UIKit                               0x022aaa5c -[UITableView cellForRowAtIndexPath:] + 235
    4   UIKit                               0x022ad6f0 -[UITableView _selectRowAtIndexPath:animated:scrollPosition:notifyDelegate:] + 1320
    5   UIKit                               0x022ad983 -[UITableView selectRowAtIndexPath:animated:scrollPosition:] + 63
    6   The City                            0x000073a2 __40-[TCMainMenuController _updateSelection]_block_invoke + 578
    7   CoreFoundation                      0x041cb13a __65-[__NSDictionaryM enumerateKeysAndObjectsWithOptions:usingBlock:]_block_invoke + 106
    8   CoreFoundation                      0x041cb03e -[__NSDictionaryM enumerateKeysAndObjectsWithOptions:usingBlock:] + 190
    9   CoreFoundation                      0x0412f525 -[NSDictionary enumerateKeysAndObjectsUsingBlock:] + 53
    10  The City                            0x0000713c -[TCMainMenuController _updateSelection] + 220
    11  The City                            0x00006999 -[TCMainMenuController viewWillAppear:] + 105
    12  UIKit                               0x022e2bfa -[UIViewController _setViewAppearState:isAnimating:] + 419
    13  UIKit                               0x022e3108 -[UIViewController __viewWillAppear:] + 114
    14  UIKit                               0x022e40c7 -[UIViewController viewWillMoveToWindow:] + 387
    15  UIKit                               0x02227384 -[UIView(Hierarchy) _willMoveToWindow:withAncestorView:] + 619
    16  UIKit                               0x02232f60 -[UIView(Internal) _addSubview:positioned:relativeTo:] + 470
    17  UIKit                               0x022269ed -[UIView(Hierarchy) insertSubview:belowSubview:] + 55
    18  The City                            0x0034c6b4 -[PPRevealSideViewController pushViewController:onDirection:withOffset:animated:forceToPopPush:completion:] + 2260
    19  The City                            0x000afc9c -[TCRootViewController pushViewController:onDirection:withOffset:animated:forceToPopPush:completion:] + 428
    20  The City                            0x0034bc9c -[PPRevealSideViewController pushViewController:onDirection:withOffset:animated:completion:] + 236
    21  The City                            0x0034b8a4 -[PPRevealSideViewController pushViewController:onDirection:animated:completion:] + 212
    22  The City                            0x0034b7b5 -[PPRevealSideViewController pushViewController:onDirection:animated:] + 149
    23  The City                            0x000af832 -[TCRootViewController showMenu] + 162
    24  The City                            0x00009a13 +[App showMenu] + 83
    25  The City                            0x00008611 -[TCMainMenuController showMenu:] + 81
    26  libobjc.A.dylib                     0x03ed6874 -[NSObject performSelector:withObject:withObject:] + 77
    27  UIKit                               0x021cd0c2 -[UIApplication sendAction:to:from:forEvent:] + 108
    28  UIKit                               0x024a1c9b -[UIBarButtonItem(UIInternal) _sendAction:withEvent:] + 139
    29  libobjc.A.dylib                     0x03ed6874 -[NSObject performSelector:withObject:withObject:] + 77
    30  UIKit                               0x021cd0c2 -[UIApplication sendAction:to:from:forEvent:] + 108
    31  UIKit                               0x021cd04e -[UIApplication sendAction:toTarget:fromSender:forEvent:] + 61
    32  UIKit                               0x022c50c1 -[UIControl sendAction:to:forEvent:] + 66
    33  UIKit                               0x022c5484 -[UIControl _sendActionsForEvents:withEvent:] + 577
    34  UIKit                               0x022c4733 -[UIControl touchesEnded:withEvent:] + 641
    35  UIKit                               0x0220a51d -[UIWindow _sendTouchesForEvent:] + 852
    36  UIKit                               0x0220b184 -[UIWindow sendEvent:] + 1232
    37  UIKit                               0x021dee86 -[UIApplication sendEvent:] + 242
    38  UIKit                               0x021c918f _UIApplicationHandleEventQueue + 11421
    39  CoreFoundation                      0x040ca83f __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 15
    40  CoreFoundation                      0x040ca1cb __CFRunLoopDoSources0 + 235
    41  CoreFoundation                      0x040e729e __CFRunLoopRun + 910
    42  CoreFoundation                      0x040e6ac3 CFRunLoopRunSpecific + 467
    43  CoreFoundation                      0x040e68db CFRunLoopRunInMode + 123
    44  GraphicsServices                    0x04f8b9e2 GSEventRunModal + 192
    45  GraphicsServices                    0x04f8b809 GSEventRun + 104
    46  UIKit                               0x021cbd3b UIApplicationMain + 1225
    47  The City                            0x000026ad main + 141
    48  libdyld.dylib                       0x0468270d start + 1
)
libc++abi.dylib: terminating with uncaught exception of type NSException

使用调试器,我可以看到 -visibleCells 虽然不为空,但没有我要选择的单元格(但它应该不在屏幕上,但应该如此)。

Using the debugger, I can see that -visibleCells, while not empty, does not have the cell I am trying to select (but it should, other than it is offscreen).

推荐答案

您的问题源自以下事实:在将控制权返回到运行循环时,会运行 -reloadData 。您现在的操作方式将导致崩溃,因为 -reloadData 直到离开该块后才执行。

Your issue stems from the fact that -reloadData is run when you return control back to the run loop. The way you're doing it right now will cause a crash because -reloadData isn't being performed until after you leave that block.

解决此问题的一种方法是调度要在下一个运行循环中运行的块:

One way to fix this is to dispatch a block to be run on the next run loop:

[self.tableView reloadData];
dispatch_async(dispatch_get_main_thread(), ^{
    [_viewControllers enumerateKeysAndObjectsUsingBlock:^(NSString *path, UIViewController *viewController, BOOL *stop) {
        if (viewController == self.revealSideViewController.rootViewController) {
            NSInteger row = [self indexOfPath:path];
            if (row != NSNotFound && row < [self.tableView numberOfRowsInSection:0]) {
                [self.tableView selectRowAtIndexPath:[NSIndexPath indexPathForRow:row inSection:0] animated:NO scrollPosition:UITableViewScrollPositionNone];
            }

            *stop = YES;
        }
    }];
});

请参阅此讨论:

See this discussion: How to tell when UITableVIew has completed ReloadData?

这篇关于调用selectRowAtIndexPath:animated:scrollPosition时崩溃:的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!