2010-09-07 19 views
0

這是我目前正在開發的源文件。這個類背後的想法是包含一個目標對象 和選擇器,它將在任何傳遞給scheduleInCFRunLoop的任何CFRunLoop中調用。我需要重複循環,而不消耗iPhone上所有可用的處理時間。任何關於完成的幫助都將是最有幫助的,我花了整整一天的時間瀏覽互聯網,試圖找到有關定製CFRunLoop資源的有用信息,我還沒有找到任何有助於完成此課程的內容。循環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 2010-09-07 23:28:20