iOS开发-Runloop中自定义输入源Source

自定义输入源

根据苹果官方文档说明,基于端口的源(Source1)由内核自动发出信号,定制源(Source0)必须从另一个线程手动发出信号

定制源Source0

创建custom input source需要定义以下内容:

  • 您希望输入源处理的信息。
  • 一个调度函数(scheduler),让感兴趣的客户端知道如何联系输入源。
  • 执行任何客户机发送的请求的处理函数(handler)。
  • 用于使输入源无效的取消函数(cancellation)。

在本例中,应用程序的Main Thread维护对Input Source的引用、该Input Source的自定义命令缓冲区以及安装输入源的运行循环。当Main Thread有一个任务要传递给Worker Thread时,它会向Command Buffer发送一个命令以及Worker Thread启动任务所需的任何信息。(因为Worker ThreadInput SourceMain Thread都可以访问Command Buffer,所以必须同步访问。)一旦发出命令,Main Thread就向Input Source发出信号,并唤醒Worker ThreadRunloop。在接收到wake up命令后,Runloop调用Input Source的处理程序,该处理程序处理在Command Buffer中找到的命令。

在这里插入图片描述
可以在主线程直接通过激活子线程的souce0,在子线程做一些事情。

附上demo https://pan.baidu.com/s/10Ao5VJgnHwC2oJSAP_5WbQ 密码:xgta

下面讲解如何实现:

自定义输入源需要使用Core Foundation来配置Runloop源并将其附加到Runloop。尽管基本的处理程序是基于C的函数,但这并不妨碍您为这些函数编写包装器,并使用Objective-C或c++实现代码主体。

@interface RunLoopSource : NSObject
{
   
    CFRunLoopSourceRef runLoopSource;
    NSMutableArray* commands;
}
 
- (id)init;
- (void)addToCurrentRunLoop;
- (void)invalidate;
 
// Handler method
- (void)sourceFired;
 
// Client interface for registering commands to process
- (void)addCommand:(NSInteger)command withData:(id)data;
- (void)fireAllCommandsOnRunLoop:(CFRunLoopRef)runloop;
 
@end
 
// These are the CFRunLoopSourceRef callback functions.
void RunLoopSourceScheduleRoutine (void *info, CFRunLoopRef rl, CFStringRef mode);
void RunLoopSourcePerformRoutine (void *info);
void RunLoopSourceCancelRoutine (void *info, CFRunLoopRef rl, CFStringRef mode);
 
// RunLoopContext is a container object used during registration of the input source.
@interface RunLoopContext : NSObject
{
   
    CFRunLoopRef        runLoop;
    RunLoopSource*        source;
}
@property (readonly) CFRunLoopRef runLoop;
@property (readonly) RunLoopSource* source;
 
- (id)initWithSource:(RunLoopSource*)src andLoop:(CFRunLoopRef)loop;
@end

回调函数

source0加入回调

RunLoopSourceScheduleRoutine回调会在你把自定义Source0加入到Runloop时,就进行回调。

我们会将source0封装到一个Context中后注册到中央代理(HCRunLoopDelegate)中。当某一方需要通过该source0触发操作时,他可以通过中央代理通信,使用Context对象中的source0来进行通信。

void RunLoopSourceScheduleRoutine (void *info, CFRunLoopRef rl, CFStringRef mode)
{
   
    NSLog(@"RunLoopSourceScheduleRoutine 对象地址 %p",info);
    RunLoopSource* obj = (__bridge RunLoopSource*)(info);
    HCRunLoopDelegate*   del 
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值