行-1或NSUIntegerMax由 - [UITableViewDelegate tableView:titleForDeleteConfirmationButtonForRowAtIndexPath:]

时间:2016-04-11 10:24:51

标签: ios objective-c uitableview cocoa-touch crash

在什么情况下,UITableView为 - [UITableViewDelegate tableView:titleForDeleteConfirmationButtonForRowAtIndexPath:]中的行提供-1或NSUIntegerMax?

下面是用户的崩溃日志。

OS Version:      iPhone OS 9.2.1 (13D15)

Application Specific Information:
*** Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'no object at index 18446744073709551615 in section at index 0'

Last Exception Backtrace:
0   CoreFoundation                      0x0000000181241900 __exceptionPreprocess + 124
1   libobjc.A.dylib                     0x00000001808aff80 objc_exception_throw + 56
2   CoreData                            0x0000000182cc50bc -[NSFetchedResultsController objectAtIndexPath:] + 456
3   My App                              0x000000010022c678 -[MyViewController tableView:titleForDeleteConfirmationButtonForRowAtIndexPath:] (MyViewController.m:560)
4   UIKit                               0x0000000186145174 -[UITableView _titleForDeleteConfirmationButtonForRowAtIndexPath:] + 160
5   UIKit                               0x00000001862756f4 -[UITableView _deleteConfirmationButtonForRowAtIndexPath:] + 116
6   UIKit                               0x0000000186275cf4 -[UITableView _swipeActionButtonsForRowAtIndexPath:] + 824
7   UIKit                               0x0000000186275998 -[UITableView _swipeActionButtons] + 92
8   UIKit                               0x0000000186144bd8 __32-[UITableViewCell _beginSwiping]_block_invoke + 120
9   UIKit                               0x0000000185f42964 +[UIView(Animation) performWithoutAnimation:] + 80
10  UIKit                               0x0000000186144b48 -[UITableViewCell _beginSwiping] + 96
11  UIKit                               0x0000000186272320 -[UITableViewWrapperView handleSwipeBeginning:] + 256
12  UIKit                               0x00000001864b4ea4 _UIGestureRecognizerSendTargetActions + 396
13  UIKit                               0x00000001860d85b8 _UIGestureRecognizerSendActions + 172
14  UIKit                               0x0000000185f669b0 -[UIGestureRecognizer _updateGestureWithEvent:buttonEvent:] + 784
15  UIKit                               0x00000001864b63bc ___UIGestureRecognizerUpdate_block_invoke904 + 72
16  UIKit                               0x0000000185f25b58 _UIGestureRecognizerRemoveObjectsFromArrayAndApplyBlocks + 372
17  UIKit                               0x0000000185f228dc _UIGestureRecognizerUpdate + 2404
18  UIKit                               0x0000000185f64820 -[UIWindow _sendGesturesForEvent:] + 1132
19  UIKit                               0x0000000185f63e1c -[UIWindow sendEvent:] + 764
20  UIKit                               0x0000000185f344cc -[UIApplication sendEvent:] + 248
21  UIKit                               0x0000000185f32794 _UIApplicationHandleEventQueue + 5528
22  CoreFoundation                      0x00000001811f8efc __CFRUNLOOP_IS_CALLING_OUT_TO_A_SOURCE0_PERFORM_FUNCTION__ + 24
23  CoreFoundation                      0x00000001811f8990 __CFRunLoopDoSources0 + 540
24  CoreFoundation                      0x00000001811f6690 __CFRunLoopRun + 724
25  CoreFoundation                      0x0000000181125680 CFRunLoopRunSpecific + 384
26  GraphicsServices                    0x0000000182634088 GSEventRunModal + 180
27  UIKit                               0x0000000185f9cd90 UIApplicationMain + 204
28  My App                              0x00000001000a926c main (main.m:16)
29  ???                                 0x0000000180cc68b8 0x0 + 0
- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath
{
    MyMessage *message = [self messageAtIndex:indexPath.row];
    if ([message.senderUid isEqualToString:mUid])
        return NSLocalizedString(@"Delete", nil);
    else
        return NSLocalizedString(@"Hide", nil);
}

- (MyMessage *)messageAtIndex:(NSInteger)index
{
    return [mMessagesController objectAtIndexPath:[NSIndexPath indexPathForRow:index inSection:0]];
}

3 个答案:

答案 0 :(得分:2)

indexPath.rowindexPath.section均为NSUInteger(无符号整数),这意味着它是严格正数。如果你减去并最终变为负数,它会跳到NSUIntegerMax。这使得必须小心涉及索引路径的算法。

row - 1 row等于零时,您将获得NSUIntegerMax

答案 1 :(得分:0)

我想答案是:在任何情况下都没有。如果您的单元格超出范围,则会在渲染时显示崩溃,而不是在访问[UITableViewDelegate tableView:titleForDeleteConfirmationButtonForRowAtIndexPath:]

所以问题与尝试从mMessagesController检索对象有关。尝试使用:

- (MyMessage *)messageAtIndex:(NSInteger)index
{
    return [[mMessagesController fetchedObjects] objectAtIndexPath:[NSIndexPath indexPathForRow:index inSection:0]];
}

- (MyMessage *)messageAtIndex:(NSInteger)index
{
    return [mMessagesController objectAtIndex:index];
}

另外,您还可以过滤对messageAtIndex的调用,以避免超出范围。

- (NSString *)tableView:(UITableView *)tableView titleForDeleteConfirmationButtonForRowAtIndexPath:(NSIndexPath *)indexPath
{
    if (indexPath.row < [mMessagesController fetchedObjects].count && indexPath.row >= 0) {
        MyMessage *message = [self messageAtIndex:indexPath.row];
        if ([message.senderUid isEqualToString:mUid])
            return NSLocalizedString(@"Delete", nil);
        else
            return NSLocalizedString(@"Hide", nil);
    } else {
        return NSLocalizedString(@"Error", nil);
    }

}

答案 2 :(得分:0)

这是一个iOS错误。 Apple将我的错误标记为23821434的副本。