• Open Menu Close Menu
  • Apple
  • Shopping Bag
  • Apple
  • Mac
  • iPad
  • iPhone
  • Watch
  • TV
  • Music
  • Support
  • Search apple.com
  • Shopping Bag

Lists

Open Menu Close Menu
  • Terms and Conditions
  • Lists hosted on this site
  • Email the Postmaster
  • Tips for posting to public mailing lists
Re: NSRunLoop looping more than once?
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: NSRunLoop looping more than once?


  • Subject: Re: NSRunLoop looping more than once?
  • From: John Anderson <email@hidden>
  • Date: Mon, 17 Mar 2003 01:44:33 -0500

Dear Julein,

Thanks for responding to my question. For the benefit of other readers, I am going to try summarize my newfound understanding of the relationship between NSTimer and NSRunLoop in this post.

(1) As Apple's Chris Kane has previously stated, a simple way to cleanly exit from a NSRunLoop (and perhaps cleanly terminate a NSThread) is like so:

while(running)[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];

where "running" is a BOOL that is originally set to YES and can be toggled by another thread or some other sequence of events.

(2) The problem that we have both apparently ran into is that [NSRunLoop runMode: beforeDate] does not return after the "NSRunLoop "runs the loop once" and "returns after ... the first input is processed" (as clearly implied by Apple's current NSRunLoop documentation) when the "input" to the NSRunLoop is a repeating NSTimer. So the code fails to poll the status to the "running" BOOL and thus fails to stop the NSRunLoop from continuing to run. Furthermore, while calling [NSTimer invalidate] does stop the timer from firing, the [NSRunLoop runMode: beforeDate] still does not return. However, a non-repeating NSTimer appears to act like a normal "input" to NSRunLoop in that [NSRunLoop runMode: beforeDate] does return after the timer fires.

(3) Now by Chris Kane's latest post, this is not a bug in NSRunLoop but rather the intended behavior. Moreover, Chris advises us to be wary of two other related scenarios that are potential pitfalls in understanding the behavior of [NSRunLoop runMode: beforeDate]. First, what exactly constitutes the processing of the "first input" may greatly be extended by recursive calls on the NSRunLoop triggered by the original input signal. Second, if the NSRunLoop is monitoring multiple input signals in its active mode, more than one signal might be processed in the same loop of execution and therefore which trying to determine which signal actually caused [NSRunLoop runMode: beforeDate] to return may be impossible.

(4) For a number of reasons, calling CFRunLoopStop (as you suggest) is probably not the best solution to the dealing with the fact that [NSRunLoop runMode: beforeDate] does not return from repeating NSTimers. Again as previously indicated by Chris Kane, using [NSRunLoop acceptInputForMode: beforeDate:[NSRunLoop limitDateForMode:]] is the way this is "supposed to be done." So, the preferred way to cleanly exit from a NSRunLoop driving by a repeating NSTimer is like so:

while(running)[[NSRunLoop currentRunLoop] acceptInputForMode:NSDefaultRunLoopMode beforeDate:[[NSRunLoop currentRunLoop] limitDateForMode:NSDefaultRunLoopMode]];

Truly yours,
John Philip Anderson
Detroit Michigan USA



On Sunday, Mar 16, 2003, at 11:07 America/Detroit, Julien Jalon wrote:


On mercredi, mars 12, 2003, at 06:48 Europe/Paris, John Anderson wrote:

Dear List,

According to Apple's documention, calling runMode: beforeDate: on
NSRunLoop "runs the loop once" and "returns after ... the first input
is processed.

So with the following code:

myTimer = [NSTimer timerWithTimeInterval:timeInterval target:self
selector:@selector(myMethod) userInfo:nil repeats:YES];

[[NSRunLoop currentRunLoop] addTimer:myTimer
forMode:NSDefaultRunLoopMode];

[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode
beforeDate:[NSDate distantFuture]];

I would expect to have "myMethod" called once when "myTimer" fires and
then control to passed on done the line.

However, this is not what happens. In fact, the NSRunLoop appears to
loop indefinitely and calls "myMethod" every time "myTimer" fires, as
if I had called run or runUntilDate: on it.

Is this supposed to happen?

If so, then what do "loop once" and "return after ... the first input
in processed" really mean?


I found this exact same problem while implementing some sort of a Time out. A timer seems not to trigger the "run loop handled a source" trick. I think we can consider it a bug but you have to use a workaround here if you want your call to runMod:beforeDate: to return even after a timer firing:

- (void)timerFired:(NSTimer *)aTimer {
// do all your work
CFRunLoopStop([[NSRunLoop currentRunLoop] getCFRunLoop]);
}

--
Julien Jalon
http://www.julien-jalon.org/
_______________________________________________
cocoa-dev mailing list | email@hidden
Help/Unsubscribe/Archives: http://www.lists.apple.com/mailman/listinfo/cocoa-dev
Do not post admin requests to the list. They will be ignored.

  • Follow-Ups:
    • Re: NSRunLoop looping more than once?
      • From: Chris Kane <email@hidden>
  • Prev by Date: Re: Detecting Keys that KeyDown doesn't get
  • Next by Date: NSHFSTypeOfFile() different behavior 10.1 and 10.2
  • Previous by thread: Re: NSRunLoop looping more than once?
  • Next by thread: Re: NSRunLoop looping more than once?
  • Index(es):
    • Date
    • Thread