Go Back   MacRumors Forums > Apple Systems and Services > Programming > Mac Programming

Reply
 
Thread Tools Search this Thread Display Modes
Old Dec 6, 2010, 11:51 AM   #1
bahlquist
macrumors member
 
Join Date: Oct 2010
Running a loop Cocoa style

I wrote a program that used an NSTimer to send a message repeatedly to the same target. Now I want to remove the timer and just have the message sent at the start of each run loop. What is the best way to do this? If I was programming in C, I would just use a while loop.
bahlquist is offline   0 Reply With Quote
Old Dec 6, 2010, 12:00 PM   #2
robbieduncan
Moderator
 
robbieduncan's Avatar
 
Join Date: Jul 2002
Location: London
Why do you want to remove the NSTimer? Any equivalent method (say calling performSelector:target:argumentrder:modes:) uses a timer on the NSRunLoop anyway...
robbieduncan is offline   0 Reply With Quote
Old Dec 6, 2010, 12:32 PM   #3
gnasher729
macrumors G5
 
gnasher729's Avatar
 
Join Date: Nov 2005
Quote:
Originally Posted by bahlquist View Post
I wrote a program that used an NSTimer to send a message repeatedly to the same target. Now I want to remove the timer and just have the message sent at the start of each run loop. What is the best way to do this? If I was programming in C, I would just use a while loop.
This doesn't make sense. The run loop is executed exactly as often as it needs to, no more, and no less. There would be no guarantee how often your code would get executed. So the best way to do this is - don't. But why don't you tell us what you actually want to achieve?
gnasher729 is online now   0 Reply With Quote
Old Dec 6, 2010, 12:37 PM   #4
GorillaPaws
macrumors 6502a
 
GorillaPaws's Avatar
 
Join Date: Oct 2003
Location: Richmond, VA
I suspect you might want to create some form of delegation or notification so your method is called when a certain periodic action occurs. As gnasher729 has said, let us know what you're trying to accomplish.
__________________
How to ask good programming questions: Getting Answers
GorillaPaws is offline   0 Reply With Quote
Old Dec 6, 2010, 12:45 PM   #5
bahlquist
Thread Starter
macrumors member
 
Join Date: Oct 2010
I just want the same method called repeatedly. In C:

Code:
while(1){myFunction();}
bahlquist is offline   0 Reply With Quote
Old Dec 6, 2010, 01:02 PM   #6
chown33
macrumors 603
 
Join Date: Aug 2009
Quote:
Originally Posted by bahlquist View Post
I just want the same method called repeatedly. In C:

Code:
while(1){myFunction();}
That's how you do it in Objective-C, too.

If you're asking how to call your function every time through a run-loop, or as fast as possible with a run-loop, then you'll have to clarify by explaining which of those you want.

Either way, it will not be identical to the while(1) loop. The reason it won't be identical is that a while(1) never pauses or breaks or does anything else. A run-loop may. If that doesn't make sense, then you should first study run-loops more. Then come up with a more precise and more detailed explanation of exactly what should happen, in what order, and at what rate. As given, your description is too vague to determine exactly what you want to happen. In particular, "at the start of each run loop" is unclear.

In studying run-loops, you should also read about CFRunLoop, not just NSRunLoop. You may also find CFRunLoopObserver to be useful.
http://developer.apple.com/library/m...057i-CH16-SW22
http://developer.apple.com/library/m...c/uid/20001442

Last edited by chown33; Dec 6, 2010 at 01:49 PM. Reason: add CFRunLoopObserver links
chown33 is offline   0 Reply With Quote
Old Dec 6, 2010, 01:12 PM   #7
Catfish_Man
macrumors 68030
 
Catfish_Man's Avatar
 
Join Date: Sep 2001
Location: Portland, OR
Send a message via AIM to Catfish_Man
Quote:
Originally Posted by bahlquist View Post
I just want the same method called repeatedly. In C:

Code:
while(1){myFunction();}

All C code is also valid Objective-C code.
Catfish_Man is offline   0 Reply With Quote
Old Dec 6, 2010, 01:55 PM   #8
bahlquist
Thread Starter
macrumors member
 
Join Date: Oct 2010
I am animating, in an OpenGL context, objects that bounce off each other. The method that I want called repeatedly is the method that updates the location of each object. At the end of the update method is
Code:
[self setNeedsDisplay:YES];
. I want the update method called once every time through the run loop. Now, according to my understanding of run loops, if I stick the code
Code:
while(1){update();}
inside a method that will be called, like, say, "awakeFromNib", then the run loop will not complete because of the infinite loop. I do not want this to happen because I want "drawRect" to be called. In any case, it seems that I should work within the structure run loop.

These are the details. In short: I want a method called once each time through the run loop. If this request doesn't make sense (and I really think it does), please tell me explicitly what my error is.
bahlquist is offline   0 Reply With Quote
Old Dec 6, 2010, 01:59 PM   #9
chown33
macrumors 603
 
Join Date: Aug 2009
You're animating. The periodic timer was already correct. Go back to it.

I don't see what you were hoping to gain by eliminating a timer. It's animation; it's supposed to be periodic.


EDITED TO ADD:
Quote:
Originally Posted by bahlquist View Post
In short: I want a method called once each time through the run loop. If this request doesn't make sense (and I really think it does), please tell me explicitly what my error is.
The error is in specifying "once each time through the run loop".

Go read "The Run Loop Sequence of Events":
http://developer.apple.com/library/m...057i-CH16-SW22

Note Step 7 is "Put the thread to sleep until...". Without a periodic timer, how would your animation be regular? Yet if you have a periodic timer, why do you need anything else other than that?

Also note that the loop may repeat several times very rapidly, if there are multiple pending tasks after a wakeup and expiration isn't reached (Step 9). If your update function is really being called once each time through the run loop, it will be called several times in rapid succession. This will occur at an irregular (untimed) rate. What will that do to the animation?

Last edited by chown33; Dec 6, 2010 at 02:14 PM.
chown33 is offline   0 Reply With Quote
Old Dec 6, 2010, 02:21 PM   #10
HiRez
macrumors 601
 
HiRez's Avatar
 
Join Date: Jan 2004
Location: Western US
Also, you should probably be using CADisplayLink instead of NSTimer to trigger your animation updates as it is more accurate and synchronized to the display's refresh interval.
__________________
Go outside, the graphics are amazing!
HiRez is online now   0 Reply With Quote
Old Dec 6, 2010, 03:00 PM   #11
kainjow
Moderator emeritus
 
kainjow's Avatar
 
Join Date: Jun 2000
Quote:
Originally Posted by HiRez View Post
Also, you should probably be using CADisplayLink instead of NSTimer to trigger your animation updates as it is more accurate and synchronized to the display's refresh interval.
but then you introduce thread safety issues, which may be a bit much at this point

EDIT: oops, I'm thinking CGDisplayLink.

Last edited by kainjow; Dec 6, 2010 at 06:40 PM.
kainjow is offline   0 Reply With Quote
Old Dec 6, 2010, 03:53 PM   #12
bahlquist
Thread Starter
macrumors member
 
Join Date: Oct 2010
chown33, I would appreciate it if you refrained from responding to my posts (seriously). Although you have helped me out at least once, on average you cause the discussion in my posts to degenerate. In particular, I don't want to have to explain why I don't want to use a timer and then argue about it.

Please, no one has addressed my original question yet.
bahlquist is offline   0 Reply With Quote
Old Dec 6, 2010, 04:02 PM   #13
gnasher729
macrumors G5
 
gnasher729's Avatar
 
Join Date: Nov 2005
Quote:
Originally Posted by bahlquist View Post
chown33, I would appreciate it if you refrained from responding to my posts (seriously). Although you have helped me out at least once, on average you cause the discussion in my posts to degenerate. In particular, I don't want to have to explain why I don't want to use a timer and then argue about it.

Please, no one has addressed my original question yet.
It's not a problem to know nothing, but it is a problem to refuse to learn. You were given the best possible advice, and you ask the person giving it not to respond to your posts?
gnasher729 is online now   0 Reply With Quote
Old Dec 6, 2010, 04:18 PM   #14
Catfish_Man
macrumors 68030
 
Catfish_Man's Avatar
 
Join Date: Sep 2001
Location: Portland, OR
Send a message via AIM to Catfish_Man
Quote:
Originally Posted by bahlquist View Post
chown33, I would appreciate it if you refrained from responding to my posts (seriously). Although you have helped me out at least once, on average you cause the discussion in my posts to degenerate. In particular, I don't want to have to explain why I don't want to use a timer and then argue about it.

Please, no one has addressed my original question yet.
Actually they have, you just don't understand the answer.

To answer the question very directly: use a runloop source. An example of a runloop source is a timer. You could also write your own custom CFRunLoopSource that signaled readiness as soon as it fired. That would probably screw up your animation though.

Probably the simplest way to do this is to use the -performSelector:afterDelay: method and pass 0 for the delay.

However, that will use a timer internally, which is apparently bad?
Catfish_Man is offline   0 Reply With Quote
Old Dec 6, 2010, 04:19 PM   #15
lee1210
macrumors 68040
 
lee1210's Avatar
 
Join Date: Jan 2005
Location: Dallas, TX
Quote:
Originally Posted by bahlquist View Post
chown33, I would appreciate it if you refrained from responding to my posts (seriously). Although you have helped me out at least once, on average you cause the discussion in my posts to degenerate. In particular, I don't want to have to explain why I don't want to use a timer and then argue about it.

Please, no one has addressed my original question yet.
It makes me sad to reply to someone who is so willing to reject help. chown33 linked to a document that explains very specifically how one would get something to occur at various points in the run loop. Specifically, you could add a run loop observer to the entrance to the run loop (for example). The document chown33 linked to provides a link to:
http://developer.apple.com/library/m...c/uid/20001442

This is the reference for setting up a run loop observer that will fire when you have requested. Of course, as others have explained, even if you read that and set it up you are not going to get the desired behavior because of the nature of the run loop. It's not doing what you're expecting. People are trying to warn you that the timer is a valid approach and there's no reason to abandon it and you are expressing that you do not want good advice, you want to know how to do the wrong thing. Those documents will tell you, but when you discover that tying into the run loop is not what you want in this case and come back looking for more help, you're going to have a harder time getting any when you are actively discouraging it.

In any case, good luck with this project and in getting assistance in the future.

-Lee
lee1210 is offline   0 Reply With Quote
Old Dec 6, 2010, 04:54 PM   #16
vocaro
macrumors regular
 
Join Date: Mar 2004
Quote:
Originally Posted by bahlquist View Post
chown33, I would appreciate it if you refrained from responding to my posts (seriously). Although you have helped me out at least once, on average you cause the discussion in my posts to degenerate.
What you perceive as degeneration is simply mass confusion caused by your own posts. You seem unable to fully explain your situation and are too quick to reject the sound advice offered to you.
vocaro is offline   0 Reply With Quote
Old Dec 6, 2010, 05:29 PM   #17
chown33
macrumors 603
 
Join Date: Aug 2009
Quote:
Originally Posted by bahlquist View Post
chown33, I would appreciate it if you refrained from responding to my posts (seriously). Although you have helped me out at least once, on average you cause the discussion in my posts to degenerate. In particular, I don't want to have to explain why I don't want to use a timer and then argue about it.
You asked for an explanation of what your error was in this:
Quote:
If this request doesn't make sense (and I really think it does), please tell me explicitly what my error is.
I gave an explanation of the error. If you wish to challenge my explanation, or refute it by pointing out errors in my explanation, then please do so. I did double-check the reference docs before writing the explanation, but I could have made a mistake. Otherwise all I can do is refer you to Apple's documentation, and note that the questions I asked are not merely rhetorical devices. They are simple logical questions that arise directly from how a run-loop works. Without a timer of some kind, how do you propose to have regular periodic animated frames? That seems like a fundamental question to me.

Perhaps you should explain why you don't want to use a timer, given the context of your error. If a run-loop cannot be made to do what you want without using a timer of some kind, then it seems logical to me that the reasons for not using a timer be explained.
chown33 is offline   0 Reply With Quote
Old Dec 6, 2010, 05:57 PM   #18
BadWolf13
macrumors 6502
 
Join Date: Dec 2009
While I know nothing about animation in Obj-C or Cocoa, I have used a do...while loop in my Obj-C programs, the same way I used them in C++. They work just fine, and the context is exactly the same.
BadWolf13 is offline   0 Reply With Quote
Old Dec 6, 2010, 06:21 PM   #19
GorillaPaws
macrumors 6502a
 
GorillaPaws's Avatar
 
Join Date: Oct 2003
Location: Richmond, VA
Quote:
Originally Posted by bahlquist View Post
chown33, I would appreciate it if you refrained from responding to my posts (seriously). Although you have helped me out at least once, on average you cause the discussion in my posts to degenerate. In particular, I don't want to have to explain why I don't want to use a timer and then argue about it.

Please, no one has addressed my original question yet.
The arrogance of that response is appaling. Read this article--at least twice.
__________________
How to ask good programming questions: Getting Answers
GorillaPaws is offline   0 Reply With Quote
Old Dec 6, 2010, 09:30 PM   #20
bahlquist
Thread Starter
macrumors member
 
Join Date: Oct 2010
Animating something by updating across irregular time intervals is not a problem: just calculate how much time has elapsed since the last update, and update using that time factor. If I am animating objects that interact with each other by colliding (in a physically realistic way), I may run into trouble if too many interactions occur in a short period of time, for the time needed to calculate the collisions may be longer than the ideal update interval length. In this case I want to compute the time of the collisions and update the locations over the whole sequence of collisions - but draw nothing until everything in the model is current. I will know when everything is current when I check for the next collision and find that it occurs in the (relatively) distant future. It is then that I will do the drawing (after one final update that coordinates the model with system time). I wouldn't want to wait to draw as I may have already waited to draw while sorting out the collisions.

It seems my answer does lie with CFRunLoopObserver, which is described in a link that was posted earlier:

http://developer.apple.com/library/m...c/uid/20001442

In particular, the "The Run Loop Sequence of Events" is helpful (I tried to look for this earlier, but didn't know what to search for):

1. Notify observers that the run loop has been entered.
2. Notify observers that any ready timers are about to fire.
3. Notify observers that any input sources that are not port based are about to fire.
4. Fire any non-port-based input sources that are ready to fire.
5. If a port-based input source is ready and waiting to fire, process the event immediately. Go to step 9.
6. Notify observers that the thread is about to sleep.
7. Put the thread to sleep until one of the following events occurs:
* An event arrives for a port-based input source.
* A timer fires.
* The timeout value set for the run loop expires.
* The run loop is explicitly woken up.
8. Notify observers that the thread just woke up.
9. Process the pending event.
* If a user-defined timer fired, process the timer event and restart the loop. Go to step 2.
* If an input source fired, deliver the event.
* If the run loop was explicitly woken up but has not yet timed out, restart the loop. Go to step 2.
10. Notify observers that the run loop has exited.
bahlquist is offline   0 Reply With Quote
Old Dec 6, 2010, 09:59 PM   #21
lloyddean
macrumors 6502a
 
Join Date: May 2009
Location: Des Moines, WA
So if I'm reading correctly an apology of some sort seems in order. Are you capable of issuing one?
lloyddean is offline   0 Reply With Quote
Old Dec 6, 2010, 10:06 PM   #22
jared_kipe
macrumors 68030
 
jared_kipe's Avatar
 
Join Date: Dec 2003
Location: Seattle
Send a message via AIM to jared_kipe
Quote:
Originally Posted by bahlquist View Post
Animating something by updating across irregular time intervals is not a problem: just calculate how much time has elapsed since the last update, and update using that time factor. If I am animating objects that interact with each other by colliding (in a physically realistic way), I may run into trouble if too many interactions occur in a short period of time, for the time needed to calculate the collisions may be longer than the ideal update interval length. In this case I want to compute the time of the collisions and update the locations over the whole sequence of collisions - but draw nothing until everything in the model is current. I will know when everything is current when I check for the next collision and find that it occurs in the (relatively) distant future. It is then that I will do the drawing (after one final update that coordinates the model with system time). I wouldn't want to wait to draw as I may have already waited to draw while sorting out the collisions.
Do you think this is the first time someone has ever tried to animate and calculate collisions? Technologies like CADisplayLink were created for just this kind of situation. Everything I've ever read about OpenGL uses a "time since last frame" approach to animation, often breaking up the modeling function from the displaying function so you can iterate over the model multiple times if too much time has passed since the last display.

Seems like maybe a book is more called for than a forum post right now.
jared_kipe is offline   0 Reply With Quote
Old Dec 6, 2010, 10:29 PM   #23
chown33
macrumors 603
 
Join Date: Aug 2009
Quote:
Originally Posted by bahlquist View Post
Animating something by updating across irregular time intervals is not a problem: just calculate how much time has elapsed since the last update, and update using that time factor. If I am animating objects that interact with each other by colliding (in a physically realistic way), I may run into trouble if too many interactions occur in a short period of time, for the time needed to calculate the collisions may be longer than the ideal update interval length. In this case I want to compute the time of the collisions and update the locations over the whole sequence of collisions - but draw nothing until everything in the model is current. I will know when everything is current when I check for the next collision and find that it occurs in the (relatively) distant future. It is then that I will do the drawing (after one final update that coordinates the model with system time). I wouldn't want to wait to draw as I may have already waited to draw while sorting out the collisions.
If you had posted that explanation to begin with, we all would have known why you removed the timer. Then I wouldn't have told you to go back to it. And I still would have pointed you to the CFRunLoop and CFRunLoopObserver reference docs.

Quote:
It seems my answer does lie with CFRunLoopObserver, which is described in a link that was posted earlier:

http://developer.apple.com/library/m...c/uid/20001442

In particular, the "The Run Loop Sequence of Events" is helpful (I tried to look for this earlier, but didn't know what to search for):
You're welcome.
chown33 is offline   0 Reply With Quote
Old Dec 7, 2010, 09:23 AM   #24
dejo
Moderator
 
dejo's Avatar
 
Join Date: Sep 2004
Location: The Centennial State
Quote:
Originally Posted by lloyddean View Post
So if I'm reading correctly an apology of some sort seems in order. Are you capable of issuing one?
Starting to look doubtful...
__________________
dejo is offline   0 Reply With Quote
Old Dec 7, 2010, 10:49 AM   #25
lloyddean
macrumors 6502a
 
Join Date: May 2009
Location: Des Moines, WA
Quote:
Originally Posted by dejo View Post
Starting to look doubtful...
Character flaws are hard to overcome.
lloyddean is offline   0 Reply With Quote

Reply
MacRumors Forums > Apple Systems and Services > Programming > Mac Programming

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Display Modes

Similar Threads
thread Thread Starter Forum Replies Last Post
Recovery Loop | Cant get iPhone 5 6.1.3 out of loop Fatush iPhone Tips, Help and Troubleshooting 1 Sep 19, 2013 09:14 PM
iPhone: iPHone 4 stuck in DFU loop then boot loop then DFU loop! urbanmacUser Jailbreaks and iOS Hacks 1 Jun 7, 2013 04:30 PM
iPhone 4 Stuck on restore loop, Help! I'm stuck on anger and frustration loop! vegas60 iPhone Tips, Help and Troubleshooting 3 Nov 8, 2012 08:49 AM
Cartoon-Style TD game---Running Rabbit HD tracyzhang iPad Apps 0 Jun 15, 2012 12:10 AM

Forum Jump

All times are GMT -5. The time now is 06:03 PM.

Mac Rumors | Mac | iPhone | iPhone Game Reviews | iPhone Apps

Mobile Version | Fixed | Fluid | Fluid HD
Copyright 2002-2013, MacRumors.com, LLC