zoukankan      html  css  js  c++  java
  • iOS学习6_多线程NSThread和GCD

    NSThread

    1.显式创建线程调用start开启

    NSThread * thread = [[NSThread alloc]initWithTarget:self selector:@selector(run:) object:_url];
    [thread start];
    
    2.隐式创建

    [NSThread detachNewThreadSelector:@selector(run:) toTarget:self withObject:_url];
    3.

    [self performSelectorInBackground:@selector(run:) withObject:_url];

    使用NSThread类似于Java里面的Thread类,线程同步等也是使用synchronized关键字。


    GCD:Grand-Central-Dispatch

    苹果提供的多核并行解决方案

    自动管理线程生命周期

    屏蔽掉了创建线程和管理线程的底层内容,让程序员使用并发编程更容易。

    两个概念:任务和队列。

    任务:要执行的操作

    队列:用来存放任务。

    定制自己的任务,然后将任务加入到队列后,GCD会自动从队列取出任务放到对应的线程执行。

    相关概念:

    同步:和当前线程是一条线,不开启线程dispatch_async函数

    异步:开启线程dispatch_sync函数

    串行队列:让任务一个接着一个执行

    并行队列:多个任务同时执行,自动开启线程,只有在异步的情况下才有效。一般使用全局并发队列

    队列决定任务怎么执行不决定是否开启线程;同步/异步决定是否开启线程。


    创建串行队列:

    dispatch_queue_attr_t attr;
    dispatch_queue_t queue = dispatch_queue_create("qhyuan",attr);

    获取全局并发队列:

    diapstch_queue_tqueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

    最常使用:

    1. 异步函数 + 并行队列

    diapstch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    dispatch_async(queue, ^{// exec task});
    dispatch_async(queue, ^{// exec task});
    dispatch_async(queue, ^{// exec task});
    

    一般会开启三个线程,并且同时执行。

    2.异步函数 + 串行队列

    dispatch_queue_attr_t attr;
    dispatch_queue_t queue = dispatch_queue_create("qhyuan", attr);
    dispatch_async(queue, ^{// exec task});
    dispatch_async(queue, ^{// exec task});
    dispatch_async(queue, ^{// exec task});
    

    开启一个线程,并且串行的执行。可以打印出线程id发现是一样的。

    3.一个特殊的串行队列:主队列

    它是一个与主线程相关的队列,自带的一个串行队列。放在主队列中的任务,不论他是同步还是异步都会在主线程中执行,注意,主队列和同步函数使用时,由于是串行的会等到当前任务执行完才会继续往下执行,所以当他后面还有代码为执行就会出问题。因此一般使用异步函数和主队列搭配使用。

    特殊之处就在于只有使用的是主队列,那么任务一定在主线程里面执行。

    dispatch_async(dispatch_get_main_queue(), ^{
        // change UI
    });
    

    GCD的其他使用:

    1.队列组:

    使用函数
    dispatch_group_async(dispatch_group_t group, dispatch_queue_t queue, ^(void){ })

    dispatch_group_t 参数就是一个队列组,可以如下创建一个队列组,dispatch_queue_t指定了block里面的任务在那里执行。

    dispatch_group_t group = dispatch_group_create();
    使用队列组的好处是,他会等到扔进队列组的所有任务执行完成后执行下面方法:

    dispatch_group_notify(dispatch_group_t group, dispatch_queue_t queue, ^(void)block);
    2.延迟执行

    [NSThread sleepForTimeInterval:];//会卡主线程
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(delayInSeconds * NSEC_PER_SEC)), queue, ^{
        // delayInSeconds秒后执行的内容
    });
    
    3.一次性代码:
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        // 这里的代码只会执行一次
    });

    线程之间的通信:在主线程修改UI

    [self performSelectorOnMainThread:(SEL) withObject:(id) waitUntilDone:(BOOL)]
    使用GCD方案:
    dispatch_async(dispatch_get_main_queue(), ^{
        //这里的代码是在主线程执行的
    });
    
    发送http请求时使用主队列,当然这里的主队列和GCD里面获取主队列不一样。
    [NSURLConnection sendAsynchronousRequest:request queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionError) {
    }];
    







  • 相关阅读:
    DOM、Window对象操作
    JavaScript基础
    关于样式表的两个练习
    css样式表
    表单
    HTML的格式、内容容器、表格标签
    C#部分的总结
    Android自定义View之音频条形图
    String, StringBuilder, StringBuffer问题
    详解Java中ArrayList、Vector、LinkedList三者的异同点(转)
  • 原文地址:https://www.cnblogs.com/qhyuan1992/p/5385302.html
Copyright © 2011-2022 走看看