Obj-C,“NSRangeException”,原因:“ -[NSMutableArray objectAtIndex:]: 索引 2 超出范围 [0 .. 1]'

发布于 2024-12-15 08:50:08 字数 2069 浏览 2 评论 0原文

前几天我发布了一个问题,但我没有包含足够的代码,并且遇到了进一步的问题。我不确定我是否应该使用 [[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;
}

I posted a question the other day, but I didn't included enough code and I'm having a further problem. I'm not sure if I should be using [[UIApplication sharedApplication] windows], but since the fix I was advise to make the other day the array doesn't have the correct amount of values.

Can someone advise / show me where I'm going wrong and if its correct to use [[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

Terminating app due to uncaught exception 'NSRangeException', reason: ' -[NSMutableArray objectAtIndex:]: index 2 beyond bounds [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;
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

琉璃梦幻 2024-12-22 08:50:08

这里的代码注释似乎已经告诉您需要做什么:

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];
}

Your code comments here appear to already tell you what you need to do:

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

Counting starts with 1, while array indexes start at 0—your two array index values are 0 (for your first window) and 1 (for your second window) but you were trying to access index value 2.

Edit: Note the following code is now completely redundant in the above:  

if(topWindowIndex < 1) { // fix 0
topWindowIndex = [allWindows count] - 1;
topWindow = [allWindows objectAtIndex:topWindowIndex];
}
猫性小仙女 2024-12-22 08:50:08

您这里的代码也是错误的:

// 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
}

This code you have here is also wrong:

// 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]];
}

What you really want is:

// 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
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文