GCD的一些高级用法

好吧,这周比较忙,没更新博客,之前的有些忘记了,先说说对项目架构的理解吧。

目前在项目中我使用的是MVC架构,后期可能会考虑转化为MVP。

        mvp的全称为Model-View-Presenter,Model提供数据,View负责显示,Controller/Presenter负责逻辑的处理。MVP与MVC有着一个重大的区别:在MVP中View并不直接使用Model,它们之间的通信是通过Presenter (MVC中的Controller)来进行的,所有的交互都发生在Presenter内部,而在MVC中View会直接从Model中读取数据而不是通过 Controller。

                                                                                                                            --------------- 百度百科

我所理解的MVP,这个P不是Presenter,而是Protocol,面向协议编程(POP),但是又不是纯纯的POP,杂糅吧,我觉得面向协议,思路更为的清晰,后期维护更为的简单便捷,阅读成本更低,而且,针对流程化元素很多的情况,感觉面向协议就是为了流程而生。。

再说说针对目前项目中多请求的情况,虽然现在没有解决问题(至少目前没有),但是我觉得已经理清楚了其中的思路,简单来说还是针对GCD的一些高级应用吧。

下面来说说leave 和enter (大都使用在等待请求数据回来之后刷新UI,循环中使用的比较多):

1、先创建对象

dispatch_group_t group = dispatch_group_create();

  2、循环执行网络请求

dispatch_group_enter(group);

for(inti =0; i < self.testAry.count; i++) {       

            [NetRequest postWithBasicParameters:dict success:^(NSDictionary *arg)  {           

                            //网络请求成功                            

                            dispatch_group_leave(group);       

            } failure:^(NSString *arg) {           

                            //网络请求失败                        

                            dispatch_group_leave(group);       

             }];   

}

  需要注意的地方:这里要注意的是无论是网络请求失败还是成功,都要调用结束方法,不然会阻塞线程。

  3、等所有循环结束后开始刷新UI

dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0), ^{ 

        .................

        [self.tableView reloadData];  // 这个注意需要在住主线程中刷新UI

});


之后再来说说GCD的信号量(控制单次的进程等待的方法。):

  信号量是用于多线程同步的,跟锁不一样的是,信号量不一定是锁定某一个资源,而是流程上的概念,比如:有A,B两个线程,B线程要等A线程完成某一任务以后再进行自己下面的步骤,这个任务 并不一定是锁定某一资源,还可以是进行一些计算或者数据处理之类。

  而对于锁来说,锁住的资源无法被其余的线程访问,从而阻塞线程而实现线程同步。

// 创建信号量

参数:信号量的初值,如果小于0则会返回

NULLdispatch_semaphore_create(信号量值)

// 等待降低信号量

dispatch_semaphore_wait(信号量,等待时间)--------> 这是一个信号量减一的过程,小于等于0,就等待。。

//提高信号量

dispatch_semaphore_signal(信号量)                    ----------> 这是一个信号量加一的过程,大于0就不阻塞线程


  3、举例

-(void)dispatchSignal{

                dispatch_semaphore_t semaphore = dispatch_semaphore_create(2);    // 参数代表并行的进程数目

                dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);   

                // task1

                dispatch_async(queue, ^{       

                        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);       

                        NSLog(@"run task 1");       

                        sleep(1);       

                        NSLog(@"complete task 1");       

                        dispatch_semaphore_signal(semaphore);        

                });

                // task2

                dispatch_async(queue, ^{       

                        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);       

                        NSLog(@"run task 2");       

                        sleep(1);       

                        NSLog(@"complete task 2");       

                        dispatch_semaphore_signal(semaphore);        

                });

                //task 3

                dispatch_async(queue, ^{       

                        dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER);       

                        NSLog(@"run task 3");       

                        sleep(1);       

                        NSLog(@"complete task 3");       

                        dispatch_semaphore_signal(semaphore);        

                }); }

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

友情链接更多精彩内容