美文网首页
iOS多线程学习笔记(二)

iOS多线程学习笔记(二)

作者: Sniper_Zheng | 来源:发表于2016-02-26 22:28 被阅读29次

    iOS多线程中的GCD
    GCD的核心:

    • 任务:执行什么操作
    • 队列:用来存放任务
      将任务添加到队列中,GCD会自动将队列中的任务取出,放到对应的线程中执行.

    同步和异步:

    dispatch_sync(<#dispatch_queue_t queue#>, <#^(void)block#>)
        
    dispatch_async(<#dispatch_queue_t queue#>, <#^(void)block#>)
    

    同步和异步的区别:

    同步:
    在当前线程中执行任务,不具备开启线程的能力
    异步:
    在新的线程中执行任务,具备开启线程的能力.但可以不开启线程

    并发:
    多个任务同时执行(只有在异步函数下才有效,因为需要开启多个线程)
    串行:
    让任务一个接着一个的执行(有点线程同步的感觉)

    用法:

    // 第一个参数:给这个队列起一个名
    // 第二个参数:DISPATCH_QUEUE_CONCURRENT
    dispatch_queue_t myQueue = dispatch_queue_create("chaqu", DISPATCH_QUEUE_CONCURRENT);
    // 接下来使用队列,并且再队列中执行一些代码
    dispatch_async(myQueue, ^{
        // 在这个block中写要执行的代码
        NSInteger a = 0;
        for (NSInteger i = 0; i < 60000001; i++) {
            a++;
        }
        NSLog(@"%ld", a);
    });
    

    自己创建的队列,如果在这个队列中执行[下载1],[下载2],[下载3] 他会依次执行任务,但是不会在主线程执行,也就是说只会开启一条子线程.并且在 MRC下 需要手动释放这个队列-> dispatch_release(myQueue)

    // GCD的第二种方法
    // 通过获取主队列,然后在进行多线程的操作
    // 获取主队列
    dispatch_queue_t mainQueue = dispatch_get_main_queue();
    dispatch_async(mainQueue, ^{
        NSInteger a = 0;
        for (NSInteger i = 0; i < 60000001; i++) {
            a++;
        }
        NSLog(@"%ld", a);
    });
    
    // GCD的经典的用法
    dispatch_async(globalQueue, ^{
        // 通过子线程加载数据,然后把数据获取之后,在主线程上现实数据内容
        NSString *strURL = @"http://su.bdimg.com/static/superplus/img/logo_white_ee663702.png";
        NSURL *url = [NSURL URLWithString:strURL];
        // 如果在主线程的时候,会卡死主线程
        NSData *data = [NSData dataWithContentsOfURL:url];
        UIImage *img = [UIImage imageWithData:data];
        // 把子线程里图片在主线程里显示
        dispatch_async(mainQueue, ^{
            // 对已经存在的图片进行赋值
            NSLog(@"显示图片");
        });
    });
    

    还有GCD的延迟执行:

    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
            // 延时1秒之后要做的操作....
        });
    

    这里如果需要延迟x秒,在子线程做操作的话,需要将队列main_queue换成全局并发队列global_queue 就可以了

    一次性代码:

    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        // 只需要执行一次的代码,比如创建单例
    });
    

    队列组:

    // 1.队列组
    dispatch_group_t group = dispatch_group_create();
    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    // 2.操作1
    __block UIImage *image1 = nil;
    dispatch_group_async(group, queue, ^{
        // 执行下载超大图片1
    });
    
    // 3.下载图片2
    __block UIImage *image2 = nil;
    dispatch_group_async(group, queue, ^{
        // 执行下载微小图片2
    });
    
    // 4.提示下载完成 (保证执行完组里面的所有任务之后,再执行notify函数里面的block)
    dispatch_group_notify(group, queue, ^{
        // 提示下载完成
    });
    

    notify的block会等group里的所有queue的任务都执行完之后才会回调.

    常用的应该就是以上,以后发现了别的GCD用法,再补上.

    相关文章

      网友评论

          本文标题:iOS多线程学习笔记(二)

          本文链接:https://www.haomeiwen.com/subject/zfewkttx.html