2010-09-07 3 views
0

Вот исходные файлы, которые я сейчас разрабатываю. Идея этого класса состоит в том, чтобы содержать целевой объект и селектор, который будет вызываться во всех CFRunLoop передан в scheduleInCFRunLoop. Мне нужно, чтобы это циклически повторялось, не потребляя все время обработки на iPhone. Любая помощь по завершению будет наиболее полезной, я потратил целый день на серфинг в Интернете, пытаясь найти полезную информацию о пользовательских источниках CFRunLoop, и я еще не нашел ничего полезного для завершения этого класса.Looping CFRunLoopSource

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) 
{ 

} 

ответ

-1

кажется мне, как вы повторно реализации NSTimer. Есть ли причина, по которой вы не можете использовать этот класс? Это в основном делает то же самое.

+1

Ну, я мог бы использовать его, я просто не хочу этого делать, потому что я хочу понять, как самому использовать RunLoops. Кроме того, я не ищу альтернативы, я ищу, как завершить свое решение. Спасибо за ваш ответ. – drreed