【问题标题】:Index beyond bounds超出范围的索引
【发布时间】:2013-09-28 18:27:24
【问题描述】:

我知道有很多类似的问题,但没有一个答案能帮助我解决我的问题。

当我移动一个窗口时我有功能:

-(void)flowLayout:(SEssentialsFlowLayout *)flow didDragView:(UIView *)view{
    NSLog(@"drag");
    BOOL needDeleteFavourites = NO;

    CGPoint dragScrollPosition =  [flow convertPoint:view.center toView:self];
    CGPoint dragPosition =  [flow convertPoint:view.center toView:self.scroll];

    // original grupe view

    UIGroupView * orgGrView = (UIGroupView *)flow.superview.superview;
    UIScrollView * orgScroll = (UIScrollView *)flow.superview;



    for (SEssentialsFlowLayout * destinationFlow in self.flows) {
        // destination grupe view
        UIGroupView * grView = (UIGroupView *)destinationFlow.superview.superview;
        UIScrollView * scroll = (UIScrollView *)destinationFlow.superview;

        if (flow != destinationFlow && grView.grupes.type == GrupeTypeEditable) {
            if (CGRectContainsPoint(destinationFlow.superview.superview.frame, dragPosition)) {

                view.center = [scroll convertPoint:dragPosition toView:scroll];

                // calculate cube space

                int numberOfCubeOnScreen = grView.frame.size.width / (grView.frame.size.height * grView.cubeWidth) ;
                int delta = grView.frame.size.width - (grView.frame.size.height * grView.cubeWidth * numberOfCubeOnScreen);
                float oneDelta = (float) delta/(numberOfCubeOnScreen );

                // destination grupe view
                int numberOfpage = ceil((grView.frame.size.height * grView.cubeWidth + oneDelta)* (destinationFlow.managedViews.count + 2) / grView.frame.size.width);
                destinationFlow.frame = CGRectMake(0, 0, grView.frame.size.width * numberOfpage, grView.frame.size.height * 0.68);

                scroll.contentSize = CGSizeMake(destinationFlow.frame.size.width, destinationFlow.frame.size.height);
                [grView.pageControll setNumberOfPages:numberOfpage];



                if (orgGrView.grupes.type == GrupeTypeNotEditable) {
                    // grabcube view
                    UICubeVeiw * oldCubeView = (UICubeVeiw *)view;

                    // create new cube and new cube view
                    Cube * newCube = [oldCubeView.cube copyCube];
                    UICubeVeiw * newCubeVew = [oldCubeView copyCubeView:oldCubeView.cube];

                    // copy new cube into old cube view
                    oldCubeView.cube = newCube;

                    // add new cube view on old flow
                    int newIndex = [flow.managedViews indexOfObject:view];
                    if (newIndex > 0 && newIndex< flow.managedViews.count) {
                        [flow unmanageSubview:view];
                        [flow addManagedSubview:newCubeVew atIndex:newIndex];

                        // move old cube view on new flow
                        [destinationFlow addManagedSubview:view];
                    }
                }
                else{

                    // original grupe view
                    int orgNumberOfpage = ceil((orgGrView.frame.size.height * grView.cubeWidth +oneDelta ) * (flow.managedViews.count ) / orgGrView.frame.size.width);
                    flow.frame = CGRectMake(0, 0, orgGrView.frame.size.width * orgNumberOfpage, orgGrView.frame.size.height * 0.68);

                    orgScroll.contentSize = CGSizeMake(flow.frame.size.width, flow.frame.size.height);
                    [orgGrView.pageControll setNumberOfPages:orgNumberOfpage];

                    [flow unmanageSubview:view];
                    [destinationFlow addManagedSubview:view];

                    [orgGrView.grupes removeCube:((UICubeVeiw *)view).cube];

                }

                needDeleteFavourites = YES;
            }
        }
    }

    NSLog(@"pozicija originala          :     %f ", orgGrView.grupes.positionIndex);
    if (orgGrView.grupes.positionIndex == 1 && needDeleteFavourites && orgGrView.grupes.cubes.count<1) {
        NSLog(@"remove");
        [self removeFavouritesFromView];
    }

    // move scroll view up and down
    if (dragScrollPosition.y < self.frame.size.height * 0.16) {
        NSLog(@"move down");
        if (!self.timerIsSet) {
            NSLog(@"move down 1");
            self.timerIsSet = YES;
            NSLog(@"move down 2");
            self.timer = [NSTimer scheduledTimerWithTimeInterval:0.5f target:self selector:@selector(moveScrollVeiwUp) userInfo:nil repeats:NO ];

        }
    }
    else if (dragScrollPosition.y > self.frame.size.height * 0.88) {
        if (!self.timerIsSet) {
            NSLog(@"move up");
            self.timerIsSet = YES;
            self.timer = [NSTimer scheduledTimerWithTimeInterval:0.5f target:self selector:@selector(moveScrollVeiwDown) userInfo:nil repeats:NO ];

        }
    }
    else{
        NSLog(@"move none");
        self.timerIsSet = NO;
        [self.timer invalidate];
        self.timer = nil;

        self.isFavouriteCurrentlyVisible = NO;
    }
}

我知道这是很多代码,但是当我移动这个窗口时,我得到了奇怪的错误:

pozicija originala          :     1.000000 
2013-09-23 20:20:31.772 BIView Mobile[659:60b] move down
2013-09-23 20:20:31.774 BIView Mobile[659:60b] *** Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 2147483646 beyond bounds [0 .. 5]'
*** First throw call stack:
(0x2db25f53 0x382996af 0x2da5c5f3 0x94667 0x942a1 0x93f1f 0x92171 0x918bf 0x91759 0x3041d98d 0x302c83e3 0x30652eed 0x3028f28b 0x3028d9d3 0x302c6c41 0x302c65e7 0x3029ba25 0x3029a221 0x2daf118b 0x2daf065b 0x2daeee4f 0x2da59ce7 0x2da59acb 0x32734283 0x302fba41 0x71655 0x387a1ab7)
libc++abi.dylib: terminating with uncaught exception of type NSException

这意味着,如果我理解正确,我应该在某处获取一些无效索引并用它查看数组。

但我总是检查索引是否在可接受值的范围内。

编辑:

按照我的建议,我设置了异常断点,但不幸的是断点在:

int main(int argc, char *argv[])
{
    @autoreleasepool {
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

如果有帮助,我会打印出堆栈跟踪:

2013-09-24 11:48:10.683 BIView Mobile[890:60b] Uncaught exception: *** -[__NSArrayM objectAtIndex:]: index 2147483646 beyond bounds [0 .. 2]
2013-09-24 11:48:10.755 BIView Mobile[890:60b] Stack trace: (
0   CoreFoundation                      0x2db25f6b <redacted> + 154
1   libobjc.A.dylib                     0x382996af objc_exception_throw + 38
2   CoreFoundation                      0x2da5c5f3 <redacted> + 230
3   BIView Mobile                       0x000e34ef -[FlowPicker isLeftMost:inOrdering:] + 58
4   BIView Mobile                       0x000e3129 -[FlowPicker widenedSubviewExcludingView:inOrdering:] + 640
5   BIView Mobile                       0x000e2da7 -[FlowPicker indexOfPoint:currentBounds:currentIndex:inOrdering:excludingView:] + 118
6   BIView Mobile                       0x000e0ff9 -[FlowEdit changeEdit:] + 524
7   BIView Mobile                       0x000e0747 -[FlowEdit fireChangeEdit:afterTimeout:] + 342
8   BIView Mobile                       0x000e05e1 -[FlowEdit handleLongPress:] + 360
9   UIKit                               0x3041d98d <redacted> + 196
10  UIKit                               0x302c83e3 <redacted> + 1138
11  UIKit                               0x30652eed <redacted> + 48
12  UIKit                               0x3028f28b <redacted> + 218
13  UIKit                               0x3028d9d3 <redacted> + 282
14  UIKit                               0x302c6c41 <redacted> + 772
15  UIKit                               0x302c65e7 <redacted> + 666
16  UIKit                               0x3029ba25 <redacted> + 196
17  UIKit                               0x3029a221 <redacted> + 7096
18  CoreFoundation                      0x2daf118b <redacted> + 14
19  CoreFoundation                      0x2daf065b <redacted> + 206
20  CoreFoundation                      0x2daeee4f <redacted> + 622
21  CoreFoundation                      0x2da59ce7 CFRunLoopRunSpecific + 522
22  CoreFoundation                      0x2da59acb CFRunLoopRunInMode + 106
23  GraphicsServices                    0x32734283 GSEventRunModal + 138
24  UIKit                               0x302fba41 UIApplicationMain + 1136
25  BIView Mobile                       0x000bf55b main + 226
26  libdyld.dylib                       0x387a1ab7 <redacted> + 2
)

【问题讨论】:

  • 那么调试器是怎么说的?
  • 如果您能确定产生此错误的准确行,将会很有帮助。如果应用程序崩溃而没有向您显示发生这种情况的位置,请尝试为所有异常添加 exception breakpoint。
  • 嗨,我尝试了,但异常断点在@autoreleasepool return UIAplicationMain 处停止......

标签: ios objective-c indexing nsarray indexoutofboundsexception


【解决方案1】:

在某些架构上,返回的索引 2147483646 恰好是 NSNotFound。您的其中一条语句(可能是[flow.managedViews indexOfObject:view])似乎返回了NSNotFound,您应该检查一下。

【讨论】:

  • 是的,我想过,但是我插入了 if (newIndex > 0 && newIndex
  • 显然这并没有解决我的问题。正如你所说,这个错误意味着 NSNotFound 并没有真正越界
  • 学习使用调试器。这应该很容易诊断。崩溃日志清楚地显示您使用索引NSNotFound 来访问数组。 NSNotFound 也总是越界。
  • 你有什么建议从哪里开始或如何调试它。我尝试了我所知道的一切,但我就是找不到它
  • 如果您在模拟器上运行调试版本,该崩溃应该会自动为您打开调试器。左侧的堆栈跟踪将准确显示它发生的位置。如果没有,请转到断点选项卡,单击左下角的“+”,然后选择“添加异常断点”。这应该会导致您的应用程序在每个异常情况下都会中断。如果它在 C++ 异常上中断(这可能是某些库中的故意),请右键单击上面添加的 Exceptions 断点,选择“Edit breakpoint”并将“Exception”从“All”更改为“Objective-C”。祝你好运!
猜你喜欢
  • 1970-01-01
  • 2018-03-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多