Search code examples
multithreadingmacoscocoaselectordelay

Cocoa-UI : Delayed performSelector .... delayed


The context :

On my mac app, when i click on a list item, a notification is sent to an object which does something in the background while on the UI there's a waiting message. All of this takes place in a window which you can quit by a "Close" button. The button by default is disabled when the notifcation is sent.

What i a want to do is a timeout feature which allows the user to quit this windows after a couple minutes hence enabling the close button.

The code :

- (IBAction)onChangeOperator:(id)sender
{
    [self performSelector:@selector(timerFired:) withObject:nil afterDelay:2.0];
    ....
    ....
    //takes time
    ....
}

-(void) timerFired:(NSTimer *) theTimer {
[close_button setEnabled:YES];
}

The problem : The button is not enabled until onChangeOperator is finished whereas i want it to be enabled as soon as selector is fired.

I think it's a thread thingy but i can't figure out.


Solution

  • From the documentation, performSelector:withObject:afterDelay:

    Invokes a method of the receiver on the current thread using the default mode after a delay.

    So the current thread is still blocked. You should instead run your expensive operation in onChangeOperator on a new thread:

    - (IBAction)onChangeOperator:(id)sender 
    {     
        [self performSelector:@selector(timerFired:) withObject:nil afterDelay:2.0];
        [self performSelectorInBackground:@selector(doUpdates) withObject:nil];
    }
    
    -(void) timerFired:(NSTimer *) theTimer 
    { 
        [close_button setEnabled:YES]; 
    } 
    
    -(void)doUpdates
    {
        .... stuff that takes time....
    }