NSIndexPath
row, section虽然定义为有符号,但是传递有符号进去,会转化成无符号, 一个负数扔进去,会变成一个很大的正数,就可以看出来是变成无符号了;
row,section, 传负数, 超过当前范围的, 都会引起scrollto滚动方法的崩溃, 用try可以捕获异常, 异常原因为Invalid indexPath;
当捕获异常后,scrollView不会任何滚动,界面看不出来
但是滚动到row为NSNotFound(也是一个很大值,有符号正数最大值,64位下为9223372036854775807)的不会崩溃,会滚动到顶端
bugly崩溃堆栈
//0 CoreFoundation ___exceptionPreprocess + 124
//1 libobjc.A.dylib objc_exception_throw + 56
//2 CoreFoundation -[NSException initWithCoder:]
//3 UIKit -[UITableView _contentOffsetForScrollingToRowAtIndexPath:atScrollPosition:usingPresentationValues:] + 1724
//4 UIKit -[UITableView _scrollToRowAtIndexPath:atScrollPosition:animated:usingPresentationValues:] + 152
//5 UIKit -[UITableView scrollToRowAtIndexPath:atScrollPosition:animated:] + 148
联机调试崩溃堆栈
//0 CoreFoundation 0x00007fff23baa1ee __exceptionPreprocess + 350
//1 libobjc.A.dylib 0x00007fff50864b20 objc_exception_throw + 48
//2 CoreFoundation 0x00007fff23ba9f68 +[NSException raise:format:arguments:] + 88
//3 Foundation 0x00007fff25614de9 -[NSAssertionHandler handleFailureInMethod:object:file:lineNumber:description:] + 191
//4 UIKitCore 0x00007fff4779dfcc -[UITableViewRowData _assertValidIndexPath:allowEmptySection:] + 962
//5 UIKitCore 0x00007fff4779e01c -[UITableViewRowData ensureHeightsFaultedInForScrollToIndexPath:withScrollPosition:boundsHeight:] + 52
//6 UIKitCore 0x00007fff47757dff -[UITableView _contentOffsetForScrollingToRowAtIndexPath:atScrollPosition:usingPresentationValues:] + 1575
//7 UIKitCore 0x00007fff47758697 -[UITableView _scrollToRowAtIndexPath:atScrollPosition:animated:usingPresentationValues:] + 142
//8 UIKitCore 0x00007fff47758543 -[UITableView scrollToRowAtIndexPath:atScrollPosition:animated:] + 135
//9 tableViewscrolltoRowAtIndexpathCras 0x0000000108594cc6 -[TableViewController testCrash:] + 726
测试代码
- (IBAction)testCrash:(id)sender {
//1, 18446744073709551516
NSIndexPath *indexpath= [NSIndexPath indexPathForRow:-100 inSection:1];
//全是有符号的
//-100, 1, -100
NSLog(@"%ld, %ld, %ld", (long)indexpath.row,(long)indexpath.section,(long)indexpath.item);
//18446744073709551516,1
indexpath= [NSIndexPath indexPathForRow:1 inSection:-100];
//1, -100, 1
NSLog(@"%ld, %ld, %ld", (long)indexpath.row,(long)indexpath.section,(long)indexpath.item);
//正常范围的不会崩溃
NSIndexPath* lastRow = [NSIndexPath indexPathForRow:(self.array.count-1) inSection:0];
//row超过了会崩溃
lastRow = [NSIndexPath indexPathForRow:1000 inSection:0];
//section超过了也会崩溃
lastRow = [NSIndexPath indexPathForRow:9 inSection:100];
//负数会变成一个很大的正数,超过了崩溃,会转成无符号的,那么当初为什么定义成有符号呢!!!
lastRow = [NSIndexPath indexPathForRow:-1 inSection:0];
//特定的NSNotFound(等于9223372036854775807),虽然超过范围,不会崩溃
//lastRow = [NSIndexPath indexPathForRow:NSNotFound inSection:0];//0,9223372036854775807
//lastRow = [NSIndexPath indexPathForRow:9223372036854775807 inSection:0];
lastRow = [NSIndexPath indexPathForRow:9223372036854775806 inSection:0];
NSLog(@"%ld",(long)NSNotFound);//static const NSInteger NSNotFound = NSIntegerMax;9223372036854775807
//NSNotFound is a valid row index for scrolling to a section with zero rows.
@try{
[self.tableView scrollToRowAtIndexPath:lastRow atScrollPosition:UITableViewScrollPositionBottom animated:YES];
}@catch(NSException*exp){
NSLog(@"exp:%@",exp.reason);//exp:Invalid indexPath
}
}
网友评论