您的位置:首页 > 理论基础 > 计算机网络

[网络和多线程]7、主队列

2015-10-01 14:57 369 查看
7、主队列
         
【网络多线程】
--------------------------------------------------------------------------------------------------------------

主队列是跟主线程相关的队列,他是GCD自带的一种特殊的串行队列,添加到主队列的
任务都会放到主线程中去执行 。主队列的获取方法是:dispatch_get_main_queue().

主队列的四种使用方式分析

(一)、在主线程同步使用

/**

 *  同步任务 ------ 主队列

 */

- (void)syncFunctMainQueue {

    

    NSLog(@"%@ --  开始",[NSThread currentThread]);

    

    // 获取主队列

    dispatch_queue_t tMainQueue = dispatch_get_main_queue();

    

    // 创建同步任务

    dispatch_sync(tMainQueue, ^{

        NSLog(@"%@ tMainQueue -- sync task1",[NSThread currentThread]);

    });

    

    dispatch_sync(tMainQueue, ^{

        NSLog(@"%@ tMainQueue -- sync task2",[NSThread currentThread]);

    });

    

    dispatch_sync(tMainQueue, ^{

        NSLog(@"%@ tMainQueue -- sync task3",[NSThread currentThread]);

    });

    

    NSLog(@"%@ -- 结束 ",[NSThread currentThread]);

}

输出:

结论:在主线程同步使用主队列会造成任务死锁,因为创建的任务被添加到队列
尾,而在主线程中同步创建任务中需要等待新建任务执行完毕后继续执行
后面的代码,因此造成死锁。

(二)、在主线程异步使用

/**

 *  异步任务 ------ 主队列

 */

- (void)asyncFunctMainQueue {

    

    NSLog(@"%@ --  开始",[NSThread currentThread]);

    

    // 获取主队列

    dispatch_queue_t tMainQueue = dispatch_get_main_queue();

    

    // 创建异步任务

    dispatch_async(tMainQueue, ^{

        NSLog(@"%@ tMainQueue -- async task1",[NSThread currentThread]);

    });

    

    dispatch_async(tMainQueue, ^{

        NSLog(@"%@ tMainQueue -- async task2",[NSThread currentThread]);

    });

    

    dispatch_async(tMainQueue, ^{

        NSLog(@"%@ tMainQueue -- async task3",[NSThread currentThread]);

    });

    

    NSLog(@"%@ -- 结束 ",[NSThread currentThread]);

}

输出:

结论:三个异步任务在主线程异步执行,而当前的任务不会挂起。

(三)、在子线程同步使用

/**

 *  同步任务 ------ 主队列

 */

- (void)syncFunctMainQueue {

    

    NSLog(@"%@ --  开始",[NSThread currentThread]);

    

    // 获取主队列

    dispatch_queue_t tMainQueue = dispatch_get_main_queue();

    

    // 创建同步任务

    dispatch_sync(tMainQueue, ^{

        NSLog(@"%@ tMainQueue -- sync task1",[NSThread currentThread]);

    });

    

    dispatch_sync(tMainQueue, ^{

        NSLog(@"%@ tMainQueue -- sync task2",[NSThread currentThread]);

    });

    

    dispatch_sync(tMainQueue, ^{

        NSLog(@"%@ tMainQueue -- sync task3",[NSThread currentThread]);

    });

    

    NSLog(@"%@ -- 结束 ",[NSThread currentThread]);

}

结论:三个任务依次在子线程中创建,子线程在创建任务完毕后会挂起,等待同步
任务执行完毕后子线程继续执行,知道三个任务都执行完毕。

(四)、在子线程异步使用

/**

 *  异步任务 ------ 主队列

 */

- (void)asyncFunctMainQueue {

    

    NSLog(@"%@ --  开始",[NSThread currentThread]);

    

    // 获取主队列

    dispatch_queue_t tMainQueue = dispatch_get_main_queue();

    

    // 
cb32
创建异步任务

    dispatch_async(tMainQueue, ^{

        NSLog(@"%@ tMainQueue -- async task1",[NSThread currentThread]);

    });

    

    dispatch_async(tMainQueue, ^{

        NSLog(@"%@ tMainQueue -- async task2",[NSThread currentThread]);

    });

    

    dispatch_async(tMainQueue, ^{

        NSLog(@"%@ tMainQueue -- async task3",[NSThread currentThread]);

    });

    

    NSLog(@"%@ -- 结束 ",[NSThread currentThread]);

}

结论:在子线程创建三个任务完毕,不挂起继续执行。三个任务回到主线程依次执
  
行。

利用GCD子线程进行图片下载

// 触摸后开始下载图片,并显示

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event

{

    // 下载图片到本地,下载费时间后台开启线程进行下载

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0),
^{

        [self downLoadPicFromNet];

    });

}

- (void)downLoadPicFromNet {

    // 下载图片资源

    NSURL *url = [NSURL URLWithString:@"http://a3.qpic.cn/psb?/76485577-db8b-

4a97-9c1e-e9d919af5bc5/5bQwZ7UhPw9GFhw3RNb*C8FlavddPlGHIrXehxNIHvw!/b/

dB4BAAAAAAAA&ek=1&kp=1&pt=0&bo=gAJxBAAAAAAFANQ!&sce=0-12-12&rf=viewer_311"];

    NSData *data = [NSData dataWithContentsOfURL:url];

    UIImage *pic = [UIImage imageWithData:data];

    

    // 返回主线程,设置图片

    dispatch_async(dispatch_get_main_queue(), ^{

        [self.imageView setImage:pic];

    });

}

// 线程间通信示例。

dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

    //执行耗时的操作

    。。。。。。。。

    dispatch_async(dispatch_get_main_queue(), ^{

        // 回到主线程执行UI刷新

        。。。。。

    });

});
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: