zoukankan      html  css  js  c++  java
  • iOS 多线程 之 GCD(大中枢派发)(二)

    本文接着上一篇讲。主要讲:dispatch_source。

    dispatch_source主要用户监听事件,可以监听如下事件

    DISPATCH_SOURCE_TYPE_DATA_ADD
    DISPATCH_SOURCE_TYPE_DATA_OR
    DISPATCH_SOURCE_TYPE_MACH_RECV
    DISPATCH_SOURCE_TYPE_MACH_SEND
    DISPATCH_SOURCE_TYPE_PROC
    DISPATCH_SOURCE_TYPE_READ
    DISPATCH_SOURCE_TYPE_SIGNAL
    DISPATCH_SOURCE_TYPE_TIMER
    DISPATCH_SOURCE_TYPE_VNODE
    DISPATCH_SOURCE_TYPE_WRITE
    DISPATCH_SOURCE_TYPE_MEMORYPRESSURE

    比较常用的就是实现Timer与自定义事件(DISPATCH_SOURCE_TYPE_DATA_ADD、DISPATCH_SOURCE_TYPE_DATA_OR)。

    一、实现timer

    使用NSTimer会有循环引用的问题,使用dispatch_source就不会有问题,代码如下

    __block NSInteger count = 0;
        dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, dispatch_get_main_queue());
        dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 2.f * NSEC_PER_SEC, 0 * NSEC_PER_SEC);
        dispatch_source_set_event_handler(timer, ^{
            NSLog(@"count == %li", count++);
        });
        dispatch_resume(timer);

    需要注意的是dispatch_source_t不会创建之后自动执行,需要显示的调用dispatch_resume才会执行,而且调用resume之后会立刻执行一次。

    二、监听用户自定义事件

    DISPATCH_SOURCE_TYPE_DATA_ADD会对用dispatch_source_merge_data提交的数据进行累加,DISPATCH_SOURCE_TYPE_DATA_OR则是对提交的数据进行或运算。示例代码如下

    @interface ViewController10 ()
    
    @property (nonatomic, strong) dispatch_source_t source;
    
    @end
    
    @implementation ViewController10
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        NSLog(@"dispatch_source_t 实现自定义事件");
        //模拟器第一次执行会有卡顿,真机不会,俺也不知道原因
        __block NSInteger total = 0;
        dispatch_source_t source = dispatch_source_create(DISPATCH_SOURCE_TYPE_DATA_ADD, 0, 0, dispatch_queue_create("com.wk.serialQueue", DISPATCH_QUEUE_CONCURRENT));
        dispatch_source_set_event_handler(source, ^{
            NSInteger result = dispatch_source_get_data(source);
            total += result;
            NSLog(@"total = %li", total);
        });
        
        dispatch_source_set_cancel_handler(source, ^{
            NSLog(@"取消了派发源");
        });
        
        dispatch_resume(source);
        
        self.source = source;
        
        dispatch_queue_t global = dispatch_get_global_queue(QOS_CLASS_UTILITY, 0);
        
        dispatch_semaphore_t semaphore = dispatch_semaphore_create(10);
        
        
        for (int i = 0; i < 100; i++) {
            dispatch_async(global, ^{
                dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);
                
                dispatch_source_merge_data(source, 1);
                
                sleep(1.f);
                
                dispatch_semaphore_signal(semaphore);
            });
        }
    }
    
    - (void)dealloc
    {
        dispatch_source_cancel(self.source);
    }
    dispatch_source_cancel可以取消派发源,使派发员不在监听指定事件
    你可以在这里下载demo
  • 相关阅读:
    1 let和const
    ECMAScript 6 扫盲
    回溯法
    13. Ajax技术
    12.JSTL标签
    11.EL(表达式语言)
    10.正则表达式(未完成)
    博客园自定义样式
    9.一次简单的Web作业
    8.JavaScript
  • 原文地址:https://www.cnblogs.com/pretty-guy/p/8241178.html
Copyright © 2011-2022 走看看