0

我有一个 NSMenu 和 3 个我想保留的静态 NSMenuItem,然后是动态生成的一堆,每次用户单击菜单图标时都应该删除并重新加载。

我正在尝试创建一个弹出的进程列表,但每次打开弹出窗口时,NSMenuItems 都不清楚。他们只是以某种时髦的方式添加。记录 for 循环表明循环没有完成。任何想法为什么?

-(void)menuNeedsUpdate:(NSMenu *)menu{

    //Keep Top 3 Menu Items
    if(dropDown.numberOfItems > 3){
        NSLog(@"-----------Removing Items");
        NSLog(@"%d",itemCount);
        for(int i = 2; i <= dropDown.numberOfItems; i++){
            NSLog(@"%d",i);
            [dropDown removeItemAtIndex:i];

        }
    }

    NSArray *appArray = [[NSWorkspace sharedWorkspace] runningApplications];


    for (NSRunningApplication *r in appArray){
        //NSLog(r.localizedName);
        //NSLog(@"------------");
        NSMenuItem *i = [[NSMenuItem alloc] initWithTitle:r.localizedName 
                                               action:@selector(fooClicked:) keyEquivalent:@""];
        [i setTarget:self];
        [dropDown addItem:i];

        [i release];
    }


}
4

1 回答 1

1

你的问题是删除代码。考虑一下:

for(int i = 3; i <= dropDown.numberOfItems; i++){
    NSLog(@"%d",i);
    [dropDown removeItemAtIndex:i];
}

它应该i--在最后。另外 - 如果数组有 3 个项目,最后一个项目的索引是 2,因此循环的声明应该如下:

for(int i = 2; i >= 0; i--){
    NSLog(@"%d",i);
    [dropDown removeItemAtIndex:i];
}

根据评论更新

从菜单中删除项目应向后或向前执行,但在第二项之后立即删除相同的项目索引(即始终删除第三项):

for(int i = 2; i <= dropDown.numberOfItems; i++){
    NSLog(@"%d",i);
    [dropDown removeItemAtIndex:2];
}

或者

for(int i = dropDown.numberOfItems; i >= 2; i--){
    NSLog(@"%d",i);
    [dropDown removeItemAtIndex:i];
}

这是必需的,因为每次删除i项目时,项目数组都会缩短,有时您会碰到超出数组边界的对象。考虑这种情况:

  1. 创建 3 个项目的数组
  2. 从 0 迭代到 2 删除第ith 项
    1. i = 0, check (i < 3 items) 去掉第一项,items数组缩短为2 (0, 1)
    2. i = 1, check (i < 2 items) 删除第一个项目,项目数组缩短为 1 (0),但只删除第二个项目,因此第 0 个项目从上一次迭代中留下(这是原始项目的第一个项目放)。

这将解释“时髦的方式”。

于 2011-09-16T06:18:05.917 回答