0

这是我目前正在开发的源文件。这个类背后的想法是包含一个目标对象和选择器,它将在传递给 scheduleInCFRunLoop的任何CFRunLoop中调用。我需要这个重复循环而不消耗 iPhone 上的所有可用处理时间。任何关于完成的帮助都是最有帮助的,我花了一整天的时间在网上冲浪,试图找到有关自定义 CFRunLoop 源的有用信息,但我还没有找到任何对完成这门课程有用的东西。

RunLoopContext.h

//
//  RunLoopContext.h
//  ETAClient-iPhoneOS
//
//  Created by Daniel Reed on 9/7/10.
//  Copyright 2010 N/a. All rights reserved.
//

#import <Foundation/Foundation.h>


@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);

RunLoopContext.m

//
//  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, &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)
{

}
4

1 回答 1

-1

在我看来,您正在重新实施NSTimer. 你不能使用那个类有什么原因吗?它基本上做同样的事情。

于 2010-09-07T23:20:08.597 回答