Obj-C,'NSRangeException',原因:' - [NSMutableArray objectAtIndex:]:索引2超出边界[0 .. 1]'

时间:2011-11-13 10:23:14

标签: objective-c xcode cocoa-touch analyzer

我前几天发布了一个问题,但是我没有提供足够的代码,而且我还有一个问题。我不确定我是否应该使用[[UIApplication sharedApplication] windows],但是自从修复后我建议前几天数组没有正确的数值。

有人可以建议/告诉我哪里出错了,以及使用[[UIApplication sharedApplication] windows]是否正确?

- (void) addDoneToKeyboard {

    doneButton.hidden =  NO;

    //Add a button to the top, above all windows
    NSArray *allWindows = [[UIApplication sharedApplication] windows];
    NSUInteger topWindowIndex = [allWindows count];// fix - 1;
    UIWindow *topWindow = [allWindows objectAtIndex:topWindowIndex]; //SIGABRT

由于未捕获的异常'NSRangeException'而终止应用程序,原因:' - [NSMutableArray objectAtIndex:]:索引2超出边界[0 .. 1]'

    // check if top window is of keypad or else
    NSString *topViewClassName = [NSString stringWithFormat:@"%@", 
             [topWindow class]];
    while (![topViewClassName isEqualToString:@"UITextEffectsWindow"] ) {
        --topWindowIndex;

        if(topWindowIndex < 1) // fix 0
            break;

        topWindow = [allWindows objectAtIndex:topWindowIndex];
        topViewClassName = [NSString stringWithFormat:@"%@", [topWindow class]];
    }

//

    if(topWindowIndex < 1) { // fix 0
        topWindowIndex = [allWindows count] - 1;
        topWindow = [allWindows objectAtIndex:topWindowIndex];
    }

    if (doneButton.superview)
        [doneButton removeFromSuperview];

    [topWindow addSubview:doneButton];

    if (!doneButtonShownRecently) {
        [UIView beginAnimations:nil context:nil];
        [UIView setAnimationBeginsFromCurrentState:YES];
        [UIView setAnimationDuration:SLIDE_IN_ANIMATION_DURATION];
        [UIView setAnimationCurve:UIViewAnimationCurveEaseInOut];
        doneButton.frame = CGRectMake(0, 480-53, 
                         doneButton.frame.size.width, 53);
        [UIView commitAnimations];
    } else {
        doneButton.frame = CGRectMake(0, 427, 
                         doneButton.frame.size.width, 53);
    }

    doneButtonShown = YES;
}

2 个答案:

答案 0 :(得分:1)

此处的代码注释似乎已经告诉您需要执行的操作:

NSUInteger topWindowIndex = [allWindows count] - 1;  
UIWindow *topWindow = [allWindows objectAtIndex:topWindowIndex];

计数从1开始,而数组索引从0开始 - 你的两个数组索引值是0(对于你的第一个窗口)和1(对于你的第二个窗口)但是你试图访问索引值2.

编辑:注意以下代码现在完全是多余的:

if(topWindowIndex < 1) { // fix 0
topWindowIndex = [allWindows count] - 1;
topWindow = [allWindows objectAtIndex:topWindowIndex];
}

答案 1 :(得分:1)

这里的代码也错了:

// check if top window is of keypad or else
NSString *topViewClassName = [NSString stringWithFormat:@"%@", 
         [topWindow class]];
while (![topViewClassName isEqualToString:@"UITextEffectsWindow"] ) {
    --topWindowIndex;

    if(topWindowIndex < 1) // fix 0
        break;

    topWindow = [allWindows objectAtIndex:topWindowIndex];
    topViewClassName = [NSString stringWithFormat:@"%@", [topWindow class]];
}

你真正想要的是:

// check if top window is of keypad or else
BOOL foundTextEffectsWindow = NO;
while (topWindowIndex >= 0) {
    topWindow = [allWindows objectAtIndex:topWindowIndex];
    if ([topWindow isKindOfClass:[UITextEffectsWindow class]]) {
      foundTextEffectsWindow = YES;
      break;
    }

    topWindowIndex--;
}
if (foundTextEffectsWindow) {
   // do stuff with the window
}