title: Looping a CFRunLoopSource
body: <p>Here is the source files I'm currently developing. The idea behind this class is to contain a target object
  and selector which will be invoked in whatever <em>CFRunLoop</em> passed to scheduleInCFRunLoop. I need this to loop repeatedly without consuming all available processing time on the iPhone. Any help on completion will be most helpful, I've spent an entire day surfing the internet trying to find helpful information regarding custom CFRunLoop sources and I am yet to find anything useful for completing this class.</p>
  
  <p><strong>RunLoopContext.h</strong></p>
  
  <pre><code>//
  //  RunLoopContext.h
  //  ETAClient-iPhoneOS
  //
  //  Created by Daniel Reed on 9/7/10.
  //  Copyright 2010 N/a. All rights reserved.
  //
  
  #import &lt;Foundation/Foundation.h&gt;
  
  
  @interface RunLoopContext : NSObject 
  {
    id target;
    SEL selector;
  
    CFRunLoopSourceContext context;
    CFRunLoopSourceRef source;
    CFRunLoopRef runLoop;
    CFStringRef mode;
  }
  
  #pragma mark -
  #pragma mark Property directives
  @property (assign) id target;
  @property (assign) SEL selector;
  @property (readonly) CFRunLoopSourceContext context;
  @property (readonly) CFRunLoopSourceRef source;
  @property (readonly) CFRunLoopRef runLoop;
  
  #pragma mark -
  #pragma mark Custom initializers
  -(id) initWithTarget: (id) aTarget selector: (SEL) aSelector;
  
  #pragma mark -
  #pragma mark Public methods
  -(BOOL) isValid;
  -(void) invalidate;
  -(void) signal;
  -(void) invoke;
  -(void) scheduleInCFRunLoop: (CFRunLoopRef) aRunLoop forMode: (CFStringRef) mode;
  @end
  
  #pragma mark -
  #pragma mark CFRunLoopSourceContext callbacks
  void RunLoopSourceScheduleRoutine (void *info, CFRunLoopRef rl, CFStringRef mode);
  void RunLoopSourcePerformRoutine (void *info);
  void RunLoopSourceCancelRoutine (void *info, CFRunLoopRef rl, CFStringRef mode);
  </code></pre>
  
  <p><strong>RunLoopContext.m</strong></p>
  
  <pre><code>//
  //  RunLoopContext.m
  //  ETAClient-iPhoneOS
  //
  //  Created by Daniel Reed on 9/7/10.
  //  Copyright 2010 N/a. All rights reserved.
  //
  
  #import "RunLoopContext.h"
  
  
  @implementation RunLoopContext
  #pragma mark -
  #pragma mark Synthesize directives
  @synthesize target;
  @synthesize selector;
  @synthesize context;
  @synthesize source;
  @synthesize runLoop;
  
  #pragma mark -
  #pragma mark Custom initializers
  -(id) initWithTarget: (id) aTarget selector: (SEL) aSelector
  {
    if (self = [super init])
    {
      target = aTarget;
      selector = aSelector;
    }
  
    return self;
  }
  
  #pragma mark -
  #pragma mark Public methods
  -(BOOL) isValid
  {
    return CFRunLoopSourceIsValid(source);
  }
  
  -(void) invalidate
  {
    CFRunLoopSourceInvalidate(source);
  }
  
  -(void) signal
  {
    CFRunLoopSourceSignal(source);
    CFRunLoopWakeUp(runLoop);
  }
  
  -(void) invoke
  {
    // Perform the target selector.
    [target performSelector: selector];
  }
  
  -(void) scheduleInCFRunLoop: (CFRunLoopRef) aRunLoop forMode: (CFStringRef) aMode
  {
    // Setup the context.
    context.version = 0;
    context.info = self;
    context.retain = NULL;
    context.release = NULL;
    context.copyDescription = CFCopyDescription;
    context.equal = CFEqual;
    context.hash = CFHash;
    context.schedule = RunLoopSourceScheduleRoutine;
    context.cancel = RunLoopSourceCancelRoutine;
    context.perform = RunLoopSourcePerformRoutine;
  
    // Store the configured runloop and mode.
    runLoop = aRunLoop;
    mode = aMode;
  
    // Create the CFRunLoopSourceRef.
    source = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &amp;context);
  
    // Add the new CFRunLoopSourceRef to the indicated runloop.
    CFRunLoopAddSource(runLoop, source, mode);
  }
  
  #pragma mark -
  #pragma mark Overriden inherited methods
  -(void) dealloc
  {
    // Invalidate.
    [self invalidate];
  
    // Set retained objects/values to nil.
    target = nil;
    selector = nil;
  
    // Invoke the inherited dealloc method.
    [super dealloc];
  }
  @end
  
  #pragma mark -
  #pragma mark CFRunLoopSourceContext callbacks
  void RunLoopSourceScheduleRoutine(void* info, CFRunLoopRef rl, CFStringRef mode)
  {
    // Cast the info pointer to a RunLoopContext instance.
    RunLoopContext* ctx = (RunLoopContext*) info;
  }
  
  void RunLoopSourcePerformRoutine (void* info)
  {
    // Cast the info pointer to a RunLoopContext instance.
    RunLoopContext* ctx = (RunLoopContext*) info;
  
    if (ctx)
    {
      [ctx invoke];
    }
  }
  
  void RunLoopSourceCancelRoutine (void* info, CFRunLoopRef rl, CFStringRef mode)
  {
  
  }
  </code></pre>