2

I have a timer within a panel that I am trying to get to fire every second, however I cannot seem to get it to fire. I am creating my panel like so:

// Begin our sheet
[NSApp beginSheet: targetController.window
   modalForWindow: self.window
    modalDelegate: self
   didEndSelector: nil
      contextInfo: nil];

Then in my targetController I have the following:

- (void) awakeFromNib
{
    NSLog(@"awakeFromNib.");
    displayUpdateTimer = [NSTimer timerWithTimeInterval: 1.0
                                                 target: self
                                               selector: @selector(updateDisplay:)
                                               userInfo: nil
                                                repeats: TRUE];

    [[NSRunLoop currentRunLoop] addTimer: displayUpdateTimer
                                 forMode: NSModalPanelRunLoopMode];
}

My understanding is that I am doing this correctly by adding the timer with the NSModalPanelRunLoopMode, however even doing so, my updateDisplay: selector never gets fired.

Does anyone have any ideas on what I am doing wrong here?

Note: I have also tried NSDefaultRunLoopMode but it made no difference. The timer was still not fired.

Edit: My overall goal is the following -

My panel has a table view that can have many items added to it at one time (from multiple threads). So I add the items into a temporary array, then when the timer fires, it adds items from the temporary array to the main array and reloads the table. Below is samples of the code doing this:

- (void) addOverwriteObject: (id) overwriteObject
{
    @synchronized(newObjects)
    {
        // Add our overwrite object
        [newObjects addObject: overwriteObject];
    } // End of overwriteObject
} // End of addOverwriteObject

And the method that fires when the timer updates:

- (void)updateDisplay:(id)sender
{
    @synchronized(newObjects)
    {
        if(newObjects.count > 0)
        {
            [overwriteObjects addObjectsFromArray: newObjects];
            [newObjects removeAllObjects];

            [tableView reloadData];
        } // End of newObjects has entries
    } // End of newObjects sync
} // End of updateDisplay

Unfortunately without the timer firing, I get no entries in the table at all.

Below is a screenshot of exactly what I am trying to do (entries have been added directly to the main array.)

enter image description here

Anoop Vaidya
  • 46,283
  • 15
  • 111
  • 140
Kyle
  • 17,317
  • 32
  • 140
  • 246
  • My guess is that you may be getting a wrong runloop. Main runloop does not work in a sheet window, it has its own one. Make sure you do not get the main runloop in awakeFromNib [NSRunLoop currentRunLoop]. If so I would try to get the correct runloop not in the awakeFromNib, but later. – Davyd Geyl Jan 17 '12 at 03:54
  • Why do you need a timer in the modal sheet anyway? – Davyd Geyl Jan 17 '12 at 03:55
  • I have added more details to try and explain exactly what I am doing. Also I tried moving the timer code to windowDidLoad rather than awakeFromNib and still no luck. – Kyle Jan 17 '12 at 12:20
  • Why don't you use MVC pattern here where model posts notification when it is actually changed and the controller subscribes to the notification and updates the table view? If for some other reason you would like to keep existing implementation, try to use `[self performSelector: withObject: afterDelay:]` instead of the timer. Call in once you displayed the window and in the end of the `updateDisplay` method; with an exit condition of course. – Davyd Geyl Jan 17 '12 at 23:38

1 Answers1

0

Your code seems to be correct,there might be the issue with run loop.Try using scheduledTimerWithTimeInterval:target:selector:userInfo:repeats:.