views:

50

answers:

2

I have some processing in my Cocoa app that sometimes ends up calling through a hierarchy of data to do a bunch of work as the result of an event. Each small piece creates and destroys some resources. I don't want those resources around most of the time, but I would like to find a smart way of creating them before all the work and killing them at the end.

Short of making those buffers etc available globally from the "parent" or elsewhere, is there a way to know locally in some code when an event loop run has ended? Then I could create them if they're not there, and keep them until the run loop ends, reusing them for any subsequent calls before that time.

EDIT: I'm not looking for suggestions on how to restructure my code, which I may do anyways. This issue just brought up the question for me of how to know when the runloop is done. If I were writing in, I dunno, Javascript, I'd use a setTimeout with zero to accomplish end-event cleanup. I suppose an NSTimer with an interval of zero might accomplish this too, but wondering if there's something cleaner.

Thanks.

A: 

I'm relatively new to programming in Cocoa, but wouldn't this just be easily accomplished by a class-level variable with a getter to that variable?

Let's say your code is like this, in pseudocode:

bool completed = false;

void chi
  if completed = false
    create foo;
    create bar;

   completed = true 
  end if

  while looping
     ...
  loop

  completed = false;
  destroy foo
  destroy bar

And within other portions of your program, check the value of 'completed' to see whether or not said objects were created?

EDIT: I just reread your question and edited accordingly. If this is a multi-threaded app you'll also need to make sure that your objects are threadsafe.

Jeffrey Kern
Yep, but the looping/traversal is happening at a much higher level in a different object than the resources are being used (buffers, etc). Those resources are being created/used/destroyed deep in nodes of the subtree, sometimes many times in an event loop.
quixoto
I think I see your idea-- make them available to whoever wants them from the "parent". This works, but is inelegant, because now children objects need to know about their parent, or some central resource allocator. (Thanks for the input. See edit to question...)
quixoto
Hmmm. Well, if you're doing a child/parent hiearchy, if the child is going to be using resources from the parent, I would think the child node needs to know who its parent is (I'm basing this off of XML Nodes and their Parent attribute). Otherwise, a static class might work. However, I undestand the pain of having to pass an object down five levels just because insignificant node X needs it :P
Jeffrey Kern
+2  A: 

Since you said "Cocoa" and "NSRunLoop", I'm going to assume you are on Mac OS X. As long as you are on Snow Leopard, you can use Grand Central Dispatch to solve this kind of problem very elegantly.

If on Leopard or later (or iPhone, for that matter), you can use NSOperations to do the same (with slightly more code).

All of this is discussed in the Concurrency Programming Guide.

Even if your algorithm isn't designed to be executed off of the Main thread -- outside of the Main event loop -- you could still solve the problem of scheduling stuff for "later", to be executed serially, via the main queue.

bbum
Thanks bbum for the info. I think my question is even simpler than this-- I guess I'm just asking if calling `– performSelectorOnMainThread:withObject:waitUntilDone:` with NO as the final param is a reasonable way to have a "run this after the event is over" handler work.
quixoto
More or less. Order is indeterminate.
bbum