在什么情况下,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]];
}
答案 0 :(得分:2)
indexPath.row
和indexPath.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的副本。