iOS--GCD(一)

来源:互联网 发布:樟木头淘宝培训 编辑:程序博客网 时间:2024/06/06 01:35

iOS中实现多线程的技术很多,但我钟爱GCD,原因如下:


1. 使用简单;

2. 效率高;

3. 苹果推荐;


工作原理:dispatch queue里添加要执行的任务,由queue管理任务的执行。


dispatch queue有两种:serial queue(串行)concurrent queue(并行) ;


serial queue(串行)

特点:queue中任何一个任务的执行,必须等到上个任务执行完毕,即A任务开始执行后需要等到执行结束后B任务便可开始执行。

使用serial queue有两种方式:获得mainQueue、创建serial queue。


1.获得mainQueue


<textarea readonly="readonly" name="code" class="objective-c”>

//获取mainQueue

dispatch_queue_t mainQueue =dispatch_get_main_queue();

//打印测试

dispatch_async(mainQueue, ^{

        NSLog(@"任务1,线程%@,是否是主线程:%d",[NSThreadcurrentThread],[[NSThreadcurrentThread]isMainThread]);

    });//block里写要执行的任务(代码)

dispatch_async(mainQueue, ^{

        NSLog(@"任务2,线程%@,是否是主线程:%d",[NSThreadcurrentThread],[[NSThreadcurrentThread]isMainThread]);

    });

dispatch_async(mainQueue, ^{

        NSLog(@"任务3,线程%@,是否是主线程:%d",[NSThreadcurrentThread],[[NSThreadcurrentThread]isMainThread]); 

    });

注:number为线程编号,1为主线程,其它均为子线程。


看打印结果便可知,使用mainQueue,所有的任务都会在主线程中按顺序执行,执行完一个才会执行下一个。



2.创建serial queue


//创建mySerialQueue

dispatch_queue_t mySerialQueue =dispatch_queue_create("com.xiaolan.GCD.mySerialQueue",DISPATCH_QUEUE_SERIAL);//苹果推荐使用反向域名格式。


dispatch_async(mySerialQueue, ^{

        NSLog(@"任务1,线程%@,是否是主线程:%d",[NSThreadcurrentThread],[[NSThreadcurrentThread]isMainThread]);

    });//block里写要执行的任务(代码)

dispatch_async(mySerialQueue, ^{

        NSLog(@"任务2,线程%@,是否是主线程:%d",[NSThreadcurrentThread],[[NSThreadcurrentThread]isMainThread]);

    });

dispatch_async(mySerialQueue, ^{

        NSLog(@"任务3,线程%@,是否是主线程:%d",[NSThreadcurrentThread],[[NSThreadcurrentThread]isMainThread]);

    }); 

      

注:number为线程编号,1为主线程,其它均为子线程。


  看打印结果便可知,使用自创建的serial queue,所有的任务都会在子线程中按顺序执行,执行完一个才会执行下一个。




concurrent queue(并行)

特点:queue中所有的任务按顺序执行,不需要等上一个任务执行完毕便可开始执行下一个任务,即A任务开始执行后不需要等到执行结束,B任务便可开始执行。

使用serial queue有两种方式:获得global queue、创建concurrent queue。


1.获得global queue


dispatch_queue_t globalQueue =dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);

//第一个参数控制globalQueue的优先级,一共有4个优先级DISPATCH_QUEUE_PRIORITY_HIGHDISPATCH_QUEUE_PRIORITY_DEFAULTDISPATCH_QUEUE_PRIORITY_LOWDISPATCH_QUEUE_PRIORITY_BACKGROUND

第二个参数是苹果预留参数,未来会用,目前填写为0.

dispatch_async(globalQueue, ^{

        NSLog(@"任务1,线程%@,是否是主线程:%d",[NSThreadcurrentThread],[[NSThreadcurrentThread]isMainThread]);

    });//block里写要执行的任务(代码)

dispatch_async(globalQueue, ^{

        NSLog(@"任务2,线程%@,是否是主线程:%d",[NSThreadcurrentThread],[[NSThreadcurrentThread]isMainThread]);

    });

 dispatch_async(globalQueue, ^{

        NSLog(@"任务3,线程%@,是否是主线程:%d",[NSThreadcurrentThread],[[NSThreadcurrentThread]isMainThread]);

    });

dispatch_async(globalQueue, ^{

        NSLog(@"任务4,线程%@,是否是主线程:%d",[NSThreadcurrentThread],[[NSThreadcurrentThread]isMainThread]);

    });

dispatch_async(globalQueue, ^{

        NSLog(@"任务5,线程%@,是否是主线程:%d",[NSThreadcurrentThread],[[NSThreadcurrentThread]isMainThread]);

    });

dispatch_async(globalQueue, ^{

        NSLog(@"任务6,线程%@,是否是主线程:%d",[NSThreadcurrentThread],[[NSThreadcurrentThread]isMainThread]); 

    });



注:number为线程编号,1为主线程,其它均为子线程。


根据打印结果暂时可以有以下几点疑虑:

为什么没有主线程参与;

即使从子线程开始6个任务为什么之开辟了5个子线程。


先不要着急,看完自创建的concurrent queue后我们进行总结。



2.创建concurrent queue


//创建myConcurrentQueue

dispatch_queue_t myConcurrentQueue =dispatch_queue_create("com.xiaolan.GCD.myConcurrentQueue",DISPATCH_QUEUE_CONCURRENT);


dispatch_async(myConcurrentQueue, ^{

        NSLog(@"任务1,线程%@,是否是主线程:%d",[NSThreadcurrentThread],[[NSThreadcurrentThread]isMainThread]);

    });//block里写要执行的任务(代码)

dispatch_async(myConcurrentQueue, ^{

        NSLog(@"任务2,线程%@,是否是主线程:%d",[NSThreadcurrentThread],[[NSThreadcurrentThread]isMainThread]);

    });

dispatch_async(myConcurrentQueue, ^{

        NSLog(@"任务3,线程%@,是否是主线程:%d",[NSThreadcurrentThread],[[NSThreadcurrentThread]isMainThread]);

    });

dispatch_async(myConcurrentQueue, ^{

        NSLog(@"任务4,线程%@,是否是主线程:%d",[NSThreadcurrentThread],[[NSThreadcurrentThread]isMainThread]);

    });

dispatch_async(myConcurrentQueue, ^{

        NSLog(@"任务5,线程%@,是否是主线程:%d",[NSThreadcurrentThread],[[NSThreadcurrentThread]isMainThread]);

    });

dispatch_async(myConcurrentQueue, ^{

        NSLog(@"任务6,线程%@,是否是主线程:%d",[NSThreadcurrentThread],[[NSThreadcurrentThread]isMainThread]); 

    });

注:number为线程编号,1为主线程,其它均为子线程。


看到这个打印结果有意思吧,记下来我们就可以总结了:

1. concurrent queue 中所有的任务都在子线程中执行;

2. 开始较晚的任务未必最后结束,开始较早的任务未必最先完成;

3. 开辟的线程数量不一定等于任务的数量,取决于多方面因素,比如:任务的数量,系统的内存资源等等,会以最优的方式开辟线程根据需要开辟适当的线程。

0 0
原创粉丝点击