搜索
您的当前位置:首页正文

iOS多线程学习笔记(二)

来源:二三娱乐

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 = 
    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用法,再补上.

Top