Best pattern to follow for scheduling an event

  • I have a method that needs to schedule a "cleanup pass" to occur in
    the near future. The method might be called once, ten times, or a
    hundred times in a row, but I only need to clean up one time. To
    implement this, I used the following pattern, and I'm wondering if it
    was the best way to go.

    First, when the object is first created, I create a timer. I
    scheduled its fire date to be in the distant, distant future:

        m_deferredFixupTimer = [[NSTimer
            scheduledTimerWithTimeInterval:DBL_MAX
                                    target:myObject
                                  selector:@selector(doFixUp:)
                                  userInfo:NULL
                                    repeats:YES] retain];

    (I considered using INFINITY instead of DBL_MAX, but sometimes
    library code isn't prepared to deal with infinite values, so I
    figured DBL_MAX is safer and already more than large enough.)
    Then, when my method is called, I schedule the timer to fire
    immediately:

        [m_deferredFixupTimer setFireDate:[NSDate date]];

    This defers the fire to the next run-through of the event loop, which
    for my purposes is sufficient. It only fires one time.

    So is this the right way to do it? It seems to work in practice, it
    just seemed a little quirky to me for some reason. I guess it would
    make more sense if I could make a timer that's scheduled to never
    fire, instead of a timer that's scheduled to repeat and fire once
    every trillion years. But in practice it seems to be equivalent.
  • On Nov 8, 2007, at 10:05 AM, John Stiles wrote:

    > I have a method that needs to schedule a "cleanup pass" to occur in
    > the near future. The method might be called once, ten times, or a
    > hundred times in a row, but I only need to clean up one time. To
    > implement this, I used the following pattern, and I'm wondering if
    > it was the best way to go.

    Have you considered using a coalescing NSNotificationQueue and
    NSPostASAP?

    j o a r
  • Le 8 nov. 07 à 19:05, John Stiles a écrit :

    > I have a method that needs to schedule a "cleanup pass" to occur in
    > the near future. The method might be called once, ten times, or a
    > hundred times in a row, but I only need to clean up one time. To
    > implement this, I used the following pattern, and I'm wondering if
    > it was the best way to go.
    >
    > First, when the object is first created, I create a timer. I
    > scheduled its fire date to be in the distant, distant future:
    >
    > m_deferredFixupTimer = [[NSTimer
    > scheduledTimerWithTimeInterval:DBL_MAX
    > target:myObject
    > selector:@selector(doFixUp:)
    > userInfo:NULL
    > repeats:YES] retain];
    >
    > (I considered using INFINITY instead of DBL_MAX, but sometimes
    > library code isn't prepared to deal with infinite values, so I
    > figured DBL_MAX is safer and already more than large enough.)
    > Then, when my method is called, I schedule the timer to fire
    > immediately:
    >
    > [m_deferredFixupTimer setFireDate:[NSDate date]];
    >
    > This defers the fire to the next run-through of the event loop,
    > which for my purposes is sufficient. It only fires one time.
    >
    > So is this the right way to do it? It seems to work in practice, it
    > just seemed a little quirky to me for some reason. I guess it would
    > make more sense if I could make a timer that's scheduled to never
    > fire, instead of a timer that's scheduled to repeat and fire once
    > every trillion years. But in practice it seems to be equivalent.

    You can maybe do something like this.

    @interface Foo : NSObject {
    BOOL shouldClean;
    }
    @end

    - (void)cleanup:(id)arg {
    shouldClean = NO;
    /* clean */
    }

    - (void)doSomethingThatRequireCleanup {
    if (!shouldClean) {
      shouldClean = YES;
      /* The aSelector message is sent to target with argument anArgument
    at the start of the next run loop iteration */
      [[NSRunLoop currentRunLoop] performSelector:@selector(cleanup:)
    target:self argument:something order:0 modes:[NSArray
    arrayWithObject:NSDefaultRunLoopMode]];
    }
    /* perform work */
    }
  • On Nov 8, 2007, at 12:05 PM, John Stiles wrote:

    > I have a method that needs to schedule a "cleanup pass" to occur in
    > the near future. The method might be called once, ten times, or a
    > hundred times in a row, but I only need to clean up one time. To
    > implement this, I used the following pattern, and I'm wondering if
    > it was the best way to go.
    >
    > First, when the object is first created, I create a timer. I
    > scheduled its fire date to be in the distant, distant future:
    >
    > m_deferredFixupTimer = [[NSTimer
    > scheduledTimerWithTimeInterval:DBL_MAX
    > target:myObject
    > selector:@selector(doFixUp:)
    > userInfo:NULL
    > repeats:YES] retain];
    >
    > Then, when my method is called, I schedule the timer to fire
    > immediately:
    >
    > [m_deferredFixupTimer setFireDate:[NSDate date]];

    What about:
    m_deferredFixupTimer = [[NSTimer alloc] initWithFireDate: [NSDate
    distantFuture] interval: 0 target: myObject selector:
    @selector(doFixUp:) userInfo: NULL repeats: NO];

    and then to get it to fire immediately

    [m_deferredFixupTimer fire];

    >
    > This defers the fire to the next run-through of the event loop,
    > which for my purposes is sufficient. It only fires one time.

    Or if you want it to be the next event loop

    [[NSRunLoop currentRunLoop] addTimer: m_deferredFixupTimer forMode:
    NSDefaultRunLoopMode];
    [m_deferredFixupTimer setFireDate: [NSDate date]];

    Glenn Andreas                      <gandreas...>
      <http://www.gandreas.com/> wicked fun!
    quadrium | prime : build, mutate, evolve, animate : the next
    generation of fractal art
  • On Nov 8, 2007, at 10:25 AM, glenn andreas wrote:

    >
    > On Nov 8, 2007, at 12:05 PM, John Stiles wrote:
    >
    >> I have a method that needs to schedule a "cleanup pass" to occur
    >> in the near future. The method might be called once, ten times, or
    >> a hundred times in a row, but I only need to clean up one time. To
    >> implement this, I used the following pattern, and I'm wondering if
    >> it was the best way to go.
    >>
    >> First, when the object is first created, I create a timer. I
    >> scheduled its fire date to be in the distant, distant future:
    >>
    >> m_deferredFixupTimer = [[NSTimer
    >> scheduledTimerWithTimeInterval:DBL_MAX
    >> target:myObject
    >> selector:@selector(doFixUp:)
    >> userInfo:NULL
    >> repeats:YES] retain];
    >>
    >> Then, when my method is called, I schedule the timer to fire
    >> immediately:
    >>
    >> [m_deferredFixupTimer setFireDate:[NSDate date]];
    >
    > What about:
    > m_deferredFixupTimer = [[NSTimer alloc] initWithFireDate: [NSDate
    > distantFuture] interval: 0 target: myObject selector: @selector
    > (doFixUp:) userInfo: NULL repeats: NO];
    >
    >
    > and then to get it to fire immediately
    >
    > [m_deferredFixupTimer fire];
    >
    >>
    >> This defers the fire to the next run-through of the event loop,
    >> which for my purposes is sufficient. It only fires one time.
    >
    >
    > Or if you want it to be the next event loop
    >
    > [[NSRunLoop currentRunLoop] addTimer: m_deferredFixupTimer
    > forMode: NSDefaultRunLoopMode];
    > [m_deferredFixupTimer setFireDate: [NSDate date]];
    >
    Would this work more than once?
    The current code works if you call it multiple times in a row.
    With a non-repeating timer, the docs say it will invalidate itself as
    soon as it has fired.
  • On Nov 8, 2007, at 12:27 PM, John Stiles wrote:

    > Would this work more than once?
    > The current code works if you call it multiple times in a row.
    > With a non-repeating timer, the docs say it will invalidate itself
    > as soon as it has fired.

    So, assuming I'm following this correctly, the cleanup happens only
    once, at the next run of the event loop, even though it may be
    requested multiple times (both between the first call and the time it
    actually runs, as well as after it has already run once).  Then the
    init part would be:

    m_deferredFixupTimer = [[NSTimer alloc] initWithFireDate: [NSDate
    distantFuture] interval: 0 target: myObject selector:
    @selector(doFixUp:) userInfo: NULL repeats: NO];
    [[NSRunLoop currentRunLoop] addTimer: m_deferredFixupTimer forMode:
    NSDefaultRunLoopMode];

    and then "trigger" part would be:
    [m_deferredFixupTimer setFireDate: [NSDate date]];
    [m_deferredFixupTimer release];
    m_deferedFixupTimer = nil;

    After the first  time it is triggered, the thing will be nil, so no
    problem...



    Glenn Andreas                      <gandreas...>
      <http://www.gandreas.com/> wicked fun!
    quadrium | flame : flame fractals & strange attractors : build,
    mutate, evolve, animate
  • I think I'm not explaining myself well enough.

    The typical pattern is that my method will get spammed a hundred
    times in quick succession. After the burst of calls has completed, I
    want to do fix-up. Technically, I could do my fix-ups after every
    single call, but that would probably be slow so I want to avoid it.
    This doesn't mean that the method will never get called again—much
    later on in app execution, it's quite possible that my method will
    suddenly get spammed again with hundreds of calls, and then I will
    want to do fix-ups again.

    The goal here is to avoid performing fix-up after every single method
    call because I know they come in bursts, but there's no easy way to
    know when the burst ends. It's pretty likely that if the event loop
    is running, though, the burst of changes has run its course.

    Consider something like text layout. An NSTextView doesn't reflow its
    entire contents every time you make a trivial change—it defers the
    big reflowing until "sometime later," again usually when the event
    loop gets a chance to run.

    On Nov 8, 2007, at 10:37 AM, glenn andreas wrote:

    >
    > On Nov 8, 2007, at 12:27 PM, John Stiles wrote:
    >
    >> Would this work more than once?
    >> The current code works if you call it multiple times in a row.
    >> With a non-repeating timer, the docs say it will invalidate itself
    >> as soon as it has fired.
    >
    >
    > So, assuming I'm following this correctly, the cleanup happens only
    > once, at the next run of the event loop, even though it may be
    > requested multiple times (both between the first call and the time
    > it actually runs, as well as after it has already run once).  Then
    > the init part would be:
    >
    > m_deferredFixupTimer = [[NSTimer alloc] initWithFireDate: [NSDate
    > distantFuture] interval: 0 target: myObject selector: @selector
    > (doFixUp:) userInfo: NULL repeats: NO];
    > [[NSRunLoop currentRunLoop] addTimer: m_deferredFixupTimer
    > forMode: NSDefaultRunLoopMode];
    >
    >
    > and then "trigger" part would be:
    > [m_deferredFixupTimer setFireDate: [NSDate date]];
    > [m_deferredFixupTimer release];
    > m_deferedFixupTimer = nil;
    >
    > After the first  time it is triggered, the thing will be nil, so no
    > problem...
    >
    >
    >
    > Glenn Andreas                      <gandreas...>
    > <http://www.gandreas.com/> wicked fun!
    > quadrium | flame : flame fractals & strange attractors : build,
    > mutate, evolve, animate
    >
    >
    >
  • Why not schedule a non-repeating timer with a time interval of zero
    from the method where you currently set the fire date.  This would
    avoid having a timer instance variable...

    dave

    On 8-Nov-07, at 11:05 AM, John Stiles wrote:

    > I have a method that needs to schedule a "cleanup pass" to occur in
    > the near future. The method might be called once, ten times, or a
    > hundred times in a row, but I only need to clean up one time. To
    > implement this, I used the following pattern, and I'm wondering if
    > it was the best way to go.
    >
    > First, when the object is first created, I create a timer. I
    > scheduled its fire date to be in the distant, distant future:
    >
    > m_deferredFixupTimer = [[NSTimer
    > scheduledTimerWithTimeInterval:DBL_MAX
    > target:myObject
    > selector:@selector(doFixUp:)
    > userInfo:NULL
    > repeats:YES] retain];
    >
    > (I considered using INFINITY instead of DBL_MAX, but sometimes
    > library code isn't prepared to deal with infinite values, so I
    > figured DBL_MAX is safer and already more than large enough.)
    > Then, when my method is called, I schedule the timer to fire
    > immediately:
    >
    > [m_deferredFixupTimer setFireDate:[NSDate date]];
    >
    > This defers the fire to the next run-through of the event loop,
    > which for my purposes is sufficient. It only fires one time.
    >
    > So is this the right way to do it? It seems to work in practice, it
    > just seemed a little quirky to me for some reason. I guess it would
    > make more sense if I could make a timer that's scheduled to never
    > fire, instead of a timer that's scheduled to repeat and fire once
    > every trillion years. But in practice it seems to be equivalent.
    >
  • On Nov 8, 2007, at 12:43 PM, John Stiles wrote:

    > I think I'm not explaining myself well enough.
    >
    > The typical pattern is that my method will get spammed a hundred
    > times in quick succession. After the burst of calls has completed, I
    > want to do fix-up. Technically, I could do my fix-ups after every
    > single call, but that would probably be slow so I want to avoid it.
    > This doesn't mean that the method will never get called again—much
    > later on in app execution, it's quite possible that my method will
    > suddenly get spammed again with hundreds of calls, and then I will
    > want to do fix-ups again.
    >

    Then have you doFixUp: routine reallocate the m_deferredFixupTimer, so
    the next time that the "do something" trigger is hit, it can be
    scheduled again.

    There is an inferred state that if m_deferredFixupTimer were nil,
    there is a pending cleanup, otherwise it means that the thing is
    currently clean (and the next time it made dirty, it will schedule a
    cleanup)

    You could even tweak the date value to guarantee that, for example,
    the cleanup only happens once every 5 seconds... (if, for example,
    part of the cleanup is to tell the user something has been updated)

    Glenn Andreas                      <gandreas...>
      <http://www.gandreas.com/> wicked fun!
    quadrium | prime : build, mutate, evolve, animate : the next
    generation of fractal art
  • On 8-Nov-07, at 11:43 AM, John Stiles wrote:

    > I think I'm not explaining myself well enough.
    >
    > The typical pattern is that my method will get spammed a hundred
    > times in quick succession. After the burst of calls has completed, I
    > want to do fix-up. Technically, I could do my fix-ups after every
    > single call, but that would probably be slow so I want to avoid it.
    > This doesn't mean that the method will never get called again—much
    > later on in app execution, it's quite possible that my method will
    > suddenly get spammed again with hundreds of calls, and then I will
    > want to do fix-ups again.
    >
    > The goal here is to avoid performing fix-up after every single
    > method call because I know they come in bursts, but there's no easy
    > way to know when the burst ends. It's pretty likely that if the
    > event loop is running, though, the burst of changes has run its
    > course.
    >

    I see.  Perhaps the following would be cleaner ...

    - (void) registerForCleanup
      {
        if (cleanupTimer != nil)
          cleanupTimer = [NSTimer scheduledTimerWithTimeInterval:0 ...
      }

    - (void) performCleanUp:(NSTimer *)sender
      {
        ...
        cleanupTimer = nil;
      }

    where cleanupTimer an instance variable.

    > Consider something like text layout. An NSTextView doesn't reflow
    > its entire contents every time you make a trivial change—it defers
    > the big reflowing until "sometime later," again usually when the
    > event loop gets a chance to run.
  • Because this would not coalesce into one call.

    On Nov 8, 2007, at 10:47 AM, David Spooner wrote:

    > Why not schedule a non-repeating timer with a time interval of zero
    > from the method where you currently set the fire date.  This would
    > avoid having a timer instance variable...
    >
    > dave
    >
    > On 8-Nov-07, at 11:05 AM, John Stiles wrote:
    >
    >> I have a method that needs to schedule a "cleanup pass" to occur
    >> in the near future. The method might be called once, ten times, or
    >> a hundred times in a row, but I only need to clean up one time. To
    >> implement this, I used the following pattern, and I'm wondering if
    >> it was the best way to go.
    >>
    >> First, when the object is first created, I create a timer. I
    >> scheduled its fire date to be in the distant, distant future:
    >>
    >> m_deferredFixupTimer = [[NSTimer
    >> scheduledTimerWithTimeInterval:DBL_MAX
    >> target:myObject
    >> selector:@selector(doFixUp:)
    >> userInfo:NULL
    >> repeats:YES] retain];
    >>
    >> (I considered using INFINITY instead of DBL_MAX, but sometimes
    >> library code isn't prepared to deal with infinite values, so I
    >> figured DBL_MAX is safer and already more than large enough.)
    >> Then, when my method is called, I schedule the timer to fire
    >> immediately:
    >>
    >> [m_deferredFixupTimer setFireDate:[NSDate date]];
    >>
    >> This defers the fire to the next run-through of the event loop,
    >> which for my purposes is sufficient. It only fires one time.
    >>
    >> So is this the right way to do it? It seems to work in practice,
    >> it just seemed a little quirky to me for some reason. I guess it
    >> would make more sense if I could make a timer that's scheduled to
    >> never fire, instead of a timer that's scheduled to repeat and fire
    >> once every trillion years. But in practice it seems to be equivalent.
    >>
    >
  • On Nov 8, 2007, at 10:57 AM, glenn andreas wrote:

    >
    > On Nov 8, 2007, at 12:43 PM, John Stiles wrote:
    >
    >> I think I'm not explaining myself well enough.
    >>
    >> The typical pattern is that my method will get spammed a hundred
    >> times in quick succession. After the burst of calls has completed,
    >> I want to do fix-up. Technically, I could do my fix-ups after
    >> every single call, but that would probably be slow so I want to
    >> avoid it. This doesn't mean that the method will never get called
    >> again—much later on in app execution, it's quite possible that my
    >> method will suddenly get spammed again with hundreds of calls, and
    >> then I will want to do fix-ups again.
    >>
    >
    > Then have you doFixUp: routine reallocate the m_deferredFixupTimer,
    > so the next time that the "do something" trigger is hit, it can be
    > scheduled again.
    >
    > There is an inferred state that if m_deferredFixupTimer were nil,
    > there is a pending cleanup, otherwise it means that the thing is
    > currently clean (and the next time it made dirty, it will schedule
    > a cleanup)
    >
    > You could even tweak the date value to guarantee that, for example,
    > the cleanup only happens once every 5 seconds... (if, for example,
    > part of the cleanup is to tell the user something has been updated)

    I guess I am struggling to see the advantage of doing things that way
    because it's more lines of code and more real work. (Extra if
    statements involved, you have to allocate and dispose the timer
    repeatedly, etc.)

    I think Joar's suggestion of a notification queue is probably the
    best approach, but it's a little more heavyweight than a timer. I
    might go that route if I find that I need more flexibility.
  • On Nov 8, 2007 11:03 AM, John Stiles <JStiles...> wrote:
    > On Nov 8, 2007, at 10:57 AM, glenn andreas wrote:
    >
    >>
    >> On Nov 8, 2007, at 12:43 PM, John Stiles wrote:
    >>
    >>> I think I'm not explaining myself well enough.
    >>>
    >>> The typical pattern is that my method will get spammed a hundred
    >>> times in quick succession. After the burst of calls has completed,
    >>> I want to do fix-up.
    >
    > I think Joar's suggestion of a notification queue is probably the
    > best approach, but it's a little more heavyweight than a timer. I
    > might go that route if I find that I need more flexibility.

    The notification queue is a fine option.  Since no one has mentioned
    it, you may also find it convenient to use
    -performSelector:withObject:afterDelay: combined with
    -cancelPreviousPerformRequestsWithTarget:selector:object:.

    -Ken
  • > I have a method that needs to schedule a "cleanup pass" to occur in
    > the near future. The method might be called once, ten times, or a
    > hundred times in a row, but I only need to clean up one time. To
    > implement this, I used the following pattern, and I'm wondering if it
    > was the best way to go.
    >
    > First, when the object is first created, I create a timer. I
    > scheduled its fire date to be in the distant, distant future:
    >
    > m_deferredFixupTimer = [[NSTimer
    > scheduledTimerWithTimeInterval:DBL_MAX
    > target:myObject
    > selector:@selector(doFixUp:)
    > userInfo:NULL
    > repeats:YES] retain];
    >
    > (I considered using INFINITY instead of DBL_MAX, but sometimes
    > library code isn't prepared to deal with infinite values, so I
    > figured DBL_MAX is safer and already more than large enough.)
    > Then, when my method is called, I schedule the timer to fire
    > immediately:
    >
    > [m_deferredFixupTimer setFireDate:[NSDate date]];
    >
    > This defers the fire to the next run-through of the event loop, which
    > for my purposes is sufficient. It only fires one time.
    >
    > So is this the right way to do it? It seems to work in practice, it
    > just seemed a little quirky to me for some reason. I guess it would
    > make more sense if I could make a timer that's scheduled to never
    > fire, instead of a timer that's scheduled to repeat and fire once
    > every trillion years. But in practice it seems to be equivalent.

    OK, how about something like this?

    @interface myObject : NSObject
    {
        NSTimer * m_deferredFixupTimer;
    }

    - (void) fixupLater(void);

    @end

    @implementation

    - (id)init
    {
        if (self = [super init])
        {
            m_deferredFixupTimer = [[NSTimer
            scheduledTimerWithTimeInterval:DBL_MAX
                                    target:myObject
                                  selector:@selector(doFixUp:)
                                  userInfo:NULL
                                    repeats:YES] retain];
        }
        return self;
    }

    - (void) fixupLater(void)
    {
        [m_deferredFixupTimer setFireDate:
                                [NSDate dateWithTimeIntervalSinceNow:1]];
    }

    @end

    (banged out rapidly, no testing, YMMV)

    Every time your call to fixupLater() is made, the timer is deferred for a
    short while.  A flurry of calls just pushes back when the fix up occurs, and
    it doesn't matter how many calls were made before the fix up happened.

    Good luck,
    Cem Karan
  • On Nov 8, 2007, at 1:05 PM, John Stiles wrote:

    > I have a method that needs to schedule a "cleanup pass" to occur in
    > the near future. The method might be called once, ten times, or a
    > hundred times in a row, but I only need to clean up one time. To
    > implement this, I used the following pattern, and I'm wondering if
    > it was the best way to go.
    >
    > First, when the object is first created, I create a timer. I
    > scheduled its fire date to be in the distant, distant future:
    >
    > m_deferredFixupTimer = [[NSTimer
    > scheduledTimerWithTimeInterval:DBL_MAX
    > target:myObject
    > selector:@selector(doFixUp:)
    > userInfo:NULL
    > repeats:YES] retain];
    >

    John, instead of using a timer you could just use a delayed perform.
    You can cancel said perform when you get a new call before re-calling
    it.

    The code would be something like this:

    - (void)cleanupMethod:(id)sender
    {
    //Your clean-up code here
    }

    - (void)doCleanup
    {
    [NSObject cancelPreviousPerformRequestsWithTarget:self
    selector:@selector(cleanupMethod:) object:self];
    [self performSelector:@selector(cleanupMethod:) withObject:self
    afterDelay:0.25];
    }

    Of course, there's caveat's doing it this way: your cleanup method
    will need to know what objects are actually being cleaned up, as it's
    not passed that info.  Doing it this way, though, your cleanup method
    would only be called once, and would only get called when objects
    actually need to be cleaned up.

    I'm not entirely certain how you have your code setup, so I don't know
    if this would be the best method to use.  But if you have some sort of
    central object that does cleanup of other objects, this would be a
    good alternative.

    I use this with sliders that are updating something in the GUI mostly,
    so that it's not updating every single time the slider's value
    changes.  You can, of course, adjust the delay to whatever works best
    for you, and if you want it to run in run loop modes other than
    NSDefaultRunLoopMode you can add in the inModes: option to the
    performSelector:... method and pass it an array of run loop modes
    you'd like it to run in.

    --------------------------------------
    Darkshadow
    (aka Michael Nickerson)
    http://www.nightproductions.net
  • This seems like a good way to go. Thanks for the tip.

    On Nov 8, 2007, at 12:01 PM, Michael Nickerson wrote:

    >
    > On Nov 8, 2007, at 1:05 PM, John Stiles wrote:
    >
    >> I have a method that needs to schedule a "cleanup pass" to occur
    >> in the near future. The method might be called once, ten times, or
    >> a hundred times in a row, but I only need to clean up one time. To
    >> implement this, I used the following pattern, and I'm wondering if
    >> it was the best way to go.
    >>
    >> First, when the object is first created, I create a timer. I
    >> scheduled its fire date to be in the distant, distant future:
    >>
    >> m_deferredFixupTimer = [[NSTimer
    >> scheduledTimerWithTimeInterval:DBL_MAX
    >> target:myObject
    >> selector:@selector(doFixUp:)
    >> userInfo:NULL
    >> repeats:YES] retain];
    >>
    >
    > John, instead of using a timer you could just use a delayed
    > perform. You can cancel said perform when you get a new call before
    > re-calling it.
    >
    > The code would be something like this:
    >
    > - (void)cleanupMethod:(id)sender
    > {
    > //Your clean-up code here
    > }
    >
    > - (void)doCleanup
    > {
    > [NSObject cancelPreviousPerformRequestsWithTarget:self
    > selector:@selector(cleanupMethod:) object:self];
    > [self performSelector:@selector(cleanupMethod:) withObject:self
    > afterDelay:0.25];
    > }
    >
    > Of course, there's caveat's doing it this way: your cleanup method
    > will need to know what objects are actually being cleaned up, as
    > it's not passed that info.  Doing it this way, though, your cleanup
    > method would only be called once, and would only get called when
    > objects actually need to be cleaned up.
    >
    > I'm not entirely certain how you have your code setup, so I don't
    > know if this would be the best method to use.  But if you have some
    > sort of central object that does cleanup of other objects, this
    > would be a good alternative.
    >
    > I use this with sliders that are updating something in the GUI
    > mostly, so that it's not updating every single time the slider's
    > value changes.  You can, of course, adjust the delay to whatever
    > works best for you, and if you want it to run in run loop modes
    > other than NSDefaultRunLoopMode you can add in the inModes: option
    > to the performSelector:... method and pass it an array of run loop
    > modes you'd like it to run in.
    >
    >
    > --------------------------------------
    > Darkshadow
    > (aka Michael Nickerson)
    > http://www.nightproductions.net
    >
    >
previous month november 2007 next month
MTWTFSS
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30    
Go to today