GCD多线程3

一、延迟执行
iOS常见的延时执行有2种方式
(1)调用NSObject的方法

- (void)performSelector:(SEL nonnull)aSelector
             withObject:(id nullable)anArgument
             afterDelay:(NSTimeInterval)delay

(2)使用GCD函数

void dispatch_after ( dispatch_time_t when, dispatch_queue_t queue, dispatch_block_t block );

- (void)viewDidLoad
{
         [super viewDidLoad];
         NSLog(@"打印线程----%@",[NSThread currentThread]);
         //延迟执行
         //第一种方法:延迟2秒钟调用run函数
         [self performSelector:@selector(run) withObject:nil afterDelay:2.0];

     }
-(void)run
 {
     NSLog(@"延迟执行----%@",[NSThread currentThread]);
 }

 -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
 {
         //在异步函数中执行
         dispatch_queue_t queue = dispatch_queue_create("willQueue", 0);

         dispatch_async(queue, ^{
                 [self performSelector:@selector(test) withObject:nil afterDelay:1.0];
             });
         NSLog(@"异步函数");
     }
 -(void)test
 {
         NSLog(@"异步函数中延迟执行----%@",[NSThread currentThread]);
}

打印结果:
这里写图片描述
结论:如果把它

- (void)performSelector:(SEL nonnull)aSelector
             withObject:(id nullable)anArgument
             afterDelay:(NSTimeInterval)delay

放在异步函数中执行,则方法不会被调用

改正:使用dispatch_after

- (void)viewDidLoad
{
         [super viewDidLoad];
    NSLog(@"打印当前线程---%@",  [NSThread currentThread]);

         //延迟执行,第二种方式
        //主队列
          dispatch_queue_t mainQueue= dispatch_get_main_queue();
         dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), mainQueue, ^{
                 NSLog(@"主队列--延迟执行------%@",[NSThread currentThread]);
             });


         //并发队列
         //1.获取全局并发队列
         dispatch_queue_t globalQueue= dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);

         //2.计算任务执行的时间
         dispatch_time_t when=dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3.0 * NSEC_PER_SEC));

         //3.会在when这个时间点,执行queue1中的这个任务
         dispatch_after(when, globalQueue, ^{
                 NSLog(@"并发队列-延迟执行------%@",[NSThread currentThread]);
             });
     }

打印结果:
这里写图片描述

延迟执行:不需要再写方法,且它还传递了一个队列,可以指定并安排其线程。

如果队列是主队列,那么就在主线程执行,如果队列是并发队列,那么会新开启一个线程,在子线程中执行。

二、一次性代码

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
 {
         static dispatch_once_t onceToken;
         dispatch_once(&onceToken, ^{
                 NSLog(@"该行代码只执行一次");
             });
     }

无论怎么点击屏幕,只打印一次。

三、队列组

步骤:

创建一个组
开启一个任务下载图片1
开启一个任务下载图片2
等group中的所有任务都执行完毕, 再回到主线程执行其他操作

-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event
{

     //http://upload.ct.youth.cn/2015/0608/1433725303485.jpg

    //创建一个队列组
    dispatch_group_t group = dispatch_group_create();

    //开启一个任务下载图片1
    __block UIImage *image1 = nil;//使用__block 可以获取在代码块中改变的值

    dispatch_group_async(group, global_queue, ^{
        image1 = [self imageWithURL:@"http://upload.ct.youth.cn/2015/0608/1433725303485.jpg"];

     NSLog(@"图片1下载完成%@---",[NSThread currentThread]);
    });

    //开启一个任务下载图片2
    __block UIImage *image2 = nil;
    dispatch_group_async(group, global_queue, ^{
        image2 = [self imageWithURL:@"http://upload.ct.youth.cn/2015/0608/1433725303485.jpg"];

        NSLog(@"图片2下载完成%@---",[NSThread currentThread]);
    });

    //等group中的所有任务都执行完毕, 再回到主线程执行其他操作

    dispatch_group_notify(group, main_queue, ^{
        NSLog(@"显示图片---%@",[NSThread currentThread]);
        self.imageView1.image = image1;
        self.imageView2.image = image2;
    });

}

打印结果:
这里写图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值