使用NSMenuItems更新动态创建的NSMenu

时间:2011-09-16 04:58:46

标签: objective-c macos osx-lion nsmenuitem nsmenu

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

我正在尝试创建一个弹出的进程列表,但每次打开弹出窗口时,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];
    }


}

1 个答案:

答案 0 :(得分: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];
}

根据评论更新

从菜单中删除项目应该向后或向前执行,但在第二项之后删除相同的项目索引(即总是删除第3项):

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,删除i
    1. i = 0,检查(i&lt; 3项)删除第一项,项目数组缩短为2(0,1)
    2. i = 1,检查(i&lt; 2项)删除第一项,项目数组缩短为1(0),但仅删除第二项,因此从上一次迭代(第1项)开始留下第0项来自原始集的项目。)
  3. 这可以解释“时髦的方式”。