一. dispatch_source_t
这里当做是一个数据类型 而dispatch_source是负责监听事件
dispatch_source_create 从字面上不难理解create(创建)一个,第一个需要填的dispatch_source_type_t,也就是需要监听的类型有很多种如下: 1.DISPATCH_SOURCE_TYPE_DATA_ADD 2.DISPATCH_SOURCE_TYPE_DATA_OR 3.DISPATCH_SOURCE_TYPE_MACH_SEND 4.DISPATCH_SOURCE_TYPE_MACH_RECV 5.DISPATCH_SOURCE_TYPE_MEMORYPRESSURE 6.DISPATCH_SOURCE_TYPE_PROC 7.DISPATCH_SOURCE_TYPE_READ 8.DISPATCH_SOURCE_TYPE_SIGNAL 9.DISPATCH_SOURCE_TYPE_TIMER 10.DISPATCH_SOURCE_TYPE_VNODE 11.DISPATCH_SOURCE_TYPE_WRITE 第二个参数需要填的是个什么?查了一下:在64位的机器上,intptr_t和uintptr_t分别是long int、unsigned long int的别名;在32位的机器上,intptr_t和uintptr_t分别是int、unsigned int的别名。但是这里填什么呢?打开api告诉这里填写一个句柄,一个常量.我又找到了如下的方法: uintptr_t dispatch_source_get_handle(<#dispatch_source_t source#>) DISPATCH_SOURCE_TYPE_DATA_ADD: n/a DISPATCH_SOURCE_TYPE_DATA_OR: n/a DISPATCH_SOURCE_TYPE_MACH_SEND: mach port (mach_port_t) DISPATCH_SOURCE_TYPE_MACH_RECV: mach port (mach_port_t) DISPATCH_SOURCE_TYPE_MEMORYPRESSURE n/a DISPATCH_SOURCE_TYPE_PROC: process identifier (pid_t) DISPATCH_SOURCE_TYPE_READ: file descriptor (int) DISPATCH_SOURCE_TYPE_SIGNAL: signal number (int) DISPATCH_SOURCE_TYPE_TIMER: n/a DISPATCH_SOURCE_TYPE_VNODE: file descriptor (int) DISPATCH_SOURCE_TYPE_WRITE: file descriptor (int) 这让我很惊讶,n/a的含义不适用,process identifier是进程的id ,file descriptor 是文件的描述,signal number是信号编号,mach_port_t查api是mach端口的用户个人空间,搞不懂.但是搞清楚了 可以填3个值:MACH_PORT_NULL,MACH_PORT_DEAD,MACH_PORT_VALID(name),分别代表,没有任何端口或端口权限;有端口但是不能用;自定义的端口名字. 目前第二个参数我用到的都是直接填0.暂且留个坑,等以后弄明白了再加上. 第三个参数从api字面上的意思是指定需要哪些事件的标志掩码.输入一个常量控制. 同样有一个方法 dispatch_source_get_mask(dispatch_source_t source) DISPATCH_SOURCE_TYPE_DATA_ADD: n/a DISPATCH_SOURCE_TYPE_DATA_OR: n/a DISPATCH_SOURCE_TYPE_MACH_SEND: dispatch_source_mach_send_flags_t DISPATCH_SOURCE_TYPE_MACH_RECV: n/a DISPATCH_SOURCE_TYPE_MEMORYPRESSURE dispatch_source_memorypressure_flags_t DISPATCH_SOURCE_TYPE_PROC: dispatch_source_proc_flags_t DISPATCH_SOURCE_TYPE_READ: n/a DISPATCH_SOURCE_TYPE_SIGNAL: n/a DISPATCH_SOURCE_TYPE_TIMER: dispatch_source_timer_flags_t DISPATCH_SOURCE_TYPE_VNODE: dispatch_source_vnode_flags_t DISPATCH_SOURCE_TYPE_WRITE: n/a 按照这个意思应该是对第二个参数的详细描述,具体到哪里填什么,挖个坑,同上一个坑一起说. 至于第四个参数是队列,意思是将这个监听放到哪一个队列里面. dispatch_source_t t = dispatch_source_create(dispatch_source_type_t type, uintptr_t handle, unsigned long mask, dispatch_queue_t queue); dispatch_source_set_event_handler第一个参数天的是给哪一个source添加事件 block中填写事件 dispatch_source_set_event_handler(dispatch_source_t source, ^{ }); 与上一个道理相同不过第二个参数传入的是函数 dispatch_source_set_event_handler_f(dispatch_source_t source, dispatch_function_t handler) //取消给定的source dispatch_source_cancel(dispatch_source_t source); //测试给定的source 如果被取消就返回非0,如果没被取消返回0 long result = dispatch_source_testcancel(dispatch_source_t source); //在取消的时候加了一个block dispatch_source_set_cancel_handler(dispatch_source_t source, ^{ }); //附上一份60秒发送短信验证码的代码供参考- (void)timer{ __block int timeout=60; //倒计时时间 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0); dispatch_source_t _timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,queue); dispatch_source_set_timer(_timer,dispatch_walltime(NULL, 0),1.0*NSEC_PER_SEC, 0); //每秒执行 dispatch_source_set_event_handler(_timer, ^{ if(timeout<=0){ //倒计时结束,关闭 dispatch_source_cancel(_timer); dispatch_async(dispatch_get_main_queue(), ^{ //设置界面的按钮显示 根据自己需求设置 [l_timeButton setTitle:@"重新发送验证码" forState:UIControlStateNormal]; l_timeButton.userInteractionEnabled = YES; }); }else{ //控制在60s内 int seconds = timeout % 60; //判断是否正好为60s if (timeout == 60) { seconds = 60; } NSString *strTime = [NSString stringWithFormat:@"%.2d", seconds]; dispatch_async(dispatch_get_main_queue(), ^{ //设置界面的按钮显示 根据自己需求设置 NSLog(@"____%@",strTime); [l_timeButton setTitle:[NSString stringWithFormat:@"%@秒后重新发送",strTime] forState:UIControlStateNormal]; l_timeButton.userInteractionEnabled = NO; }); timeout--; } }); dispatch_resume(_timer); }新闻热点
疑难解答