Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

pflau

macrumors 6502
Original poster
Sep 17, 2007
410
46
Hi. I have a function that needs to be called repeatedly for the entire duration of the program, is there an infinite loop in Cocoa that I can stick this function in? For instance, in Windows, I can write something like

Code:
LRESULT MyWindow::WindowProc(UINT message, WPARAM wParam, LPARAM lParam)
{
      myFunction();
     // OnWndMsg does most of the work, except for DefWindowProc call
     LRESULT lResult = 0;
     if (!OnWndMsg(message, wParam, lParam, &lResult))
          lResult = DefWindowProc(message, wParam, lParam);
     return lResult;
}

and stick myFunction into the WindowProc.

Basically, WindowProc is called by Windows in an infinite loop to check and dispatch messages. I override this function so it would call my function as well. This way I save myself a thread and I don't need to deal with asynchronous access to my data.

I wonder if there is anything similar in Cocoa. Thanks.
 
Your requirements are satisfied by using a repeating timer.

That is certainly true. However, the mandatory timer interval is not ideal when you're in a high volume, low latency environment where your application must loop as fast as it can even at the expense of CPU consumption. Think about high frequency trading and realtime market data.
 
That is certainly true. However, the mandatory timer interval is not ideal when you're in a high volume, low latency environment where your application must loop as fast as it can even at the expense of CPU consumption. Think about high frequency trading and realtime market data.

So this is actually an I/O bound problem.

  • Use asynchronous network APIs and kick off an initial request
  • when new data arrives kick off a new request
  • process that data while the new request is active
 
It is not an I/O bound problem. There is no requirement that all input must be process. There IS the requirement that the process MUST take place as fast as possible. So it is a CPU bound problem - using an infinite loop is thus the best way to take up as much CPU time as possible.
 
The NSRunLoop is similar in idea to your WindowProc. An NSTimer scheduled at a very short repeat will actually get called every time through the run loop (which is an infinite loop to the point the app ends). Or to ensure your method is called every time through the loop call performSelector:target:argument:eek:rder:modes: on the current run loop and call the same at the end of the method to schedule again for the next time through the loop.
 
The NSRunLoop is similar in idea to your WindowProc. An NSTimer scheduled at a very short repeat will actually get called every time through the run loop (which is an infinite loop to the point the app ends). Or to ensure your method is called every time through the loop call performSelector:target:argument:eek:rder:modes: on the current run loop and call the same at the end of the method to schedule again for the next time through the loop.

I wonder how small I can make the timer interval value.. like 0.0001 or some rediculous number. Anyway, calling NSRunLoop's performSelector repeatedly is definitely clever.. I did not considered that when Iooked at it initially.
 
Just consider how long the method you schedule takes to run each time: if you block the main runloop the UI will freeze...
 
Maybe use a CFRunLoopObserver. Google it. Read its reference docs. Then look up CFRunLoop and NSRunLoop's getCFRunLoop method.

If you're really trying to write a high frequency trading app for iOS, my guess is it's probably doomed. You're unavoidably at the mercy of wifi latencies and other protocol delays, in addition to any kernel scheduling delays, or being pre-empted due to display or audio needs that your app has no control over. Neither iOS, nor Mac OS X, nor Windows is a real-time OS.

EDIT:
No matter what you eventually use, you really need to test it on a device, and under adverse conditions. For example, playing audio in the background will take resources, and audio processing effectively has higher priority. Since your app can't control whether the user is playing iTunes (or other audio, or other apps) at the same time, you have to accept whatever the OS does behind your back.
 
No I am not really writing a high frequency trading app.. that was just an analogy. My initial reference to the WinProc procedure was how clean the implementation was. If we are to get into using an observer and all that, then it is starting to negate the benefit of keeping everything in the same thread and I might as well create another thread and do the semaphore/mutex thing.
 
Why switch to the (somewhat more costly) thread-based approach, when you can use NSRunLoop's performSelector?

This is, in fact, essentially the same as hooking WindowProc and calling PostMessage, right?
 
You could consider using CFRunLoopTimer directly and avoid Objective-C altogether...
 
I wonder how small I can make the timer interval value.. like 0.0001 or some rediculous number. Anyway, calling NSRunLoop's performSelector repeatedly is definitely clever.. I did not considered that when Iooked at it initially.

If you're trying to update the UI, there is very little point in scheduling something to happen faster than the main runloop as the screen will not redraw faster than the main runloop anyway.
 
Hi. I have a function that needs to be called repeatedly for the entire duration of the program, is there an infinite loop in Cocoa that I can stick this function in? .


Have you tried standing outside in Apple's parking lot.


Sorry I had to.
 
I smell premature optimization. Why not start off with a repeating timer once every second and see if you can even process the data fast enough.

Maybe I'm not thinking outside the box enough, but I fail to see what kind of "realtime market data" could possibly be processed or needed every 0.0001seconds.
 
If you're trying to update the UI, there is very little point in scheduling something to happen faster than the main runloop as the screen will not redraw faster than the main runloop anyway.

Precisely my point.
 
So what is the problem?

The problem was to find an infinite loop. One of the solutions suggested was to use a timer, and I said it is not ideal because it mandates a timer interval. Doing so makes an assumption about how fast the GUI can update. A real infinite loop on the other hand guarantees that it provides data as fast as the GUI can handle.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.