I have a NSMenu with 3 static NSMenuItems that I want to keep, and a bunch after that are dynamically generated and should be removed and reloaded each time the user clicks the menu icon.
I'm trying to create a list of processes that pop out, but each time I open the popout, the NSMenuItems don't clear. They just add on in some funky way. Logging the for loop shows that the loop isn't completing. Any ideas why?
-(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];
}
}
your problem is with removal code. Consider this:
for(int i = 3; i <= dropDown.numberOfItems; i++){
NSLog(@"%d",i);
[dropDown removeItemAtIndex:i];
}
It should be i--
at the end. Also - if array has 3 items, the index of last item is 2, hence the declaration of the loop should be following:
for(int i = 2; i >= 0; i--){
NSLog(@"%d",i);
[dropDown removeItemAtIndex:i];
}
Update according to comment
Removing the items from your menu should be performed backwards or forward, but removing same item index right next after the 2nd item (i.e. removing always 3rd item):
for(int i = 2; i <= dropDown.numberOfItems; i++){
NSLog(@"%d",i);
[dropDown removeItemAtIndex:2];
}
or
for(int i = dropDown.numberOfItems; i >= 2; i--){
NSLog(@"%d",i);
[dropDown removeItemAtIndex:i];
}
This is needed because each time you remove i
th item, the array of items shortens and sometimes you hit the object that is beyond array bounds. Consider this scenario:
i
th item
This would explain the "funky way".