iOS软件开发iOSiOS Developer

GCD温故而知新1

2016-11-09  本文已影响65人  大墙66370

GCD 三中queue
1.1 main queue
1.2 global queue
1.3 自己创建 queue
1.3.1 自己创建 queue 分两种
1>串行 dispatch_queue_t serial_queue = dispatch_queue_create("lcc", DISPATCH_QUEUE_SERIAL);
2>并行 dispatch_queue_t serial_concurrent = dispatch_queue_create("lccc", DISPATCH_QUEUE_CONCURRENT);

线程 有两种
2.1 sync 同步
2.2 async 异步

//异步 主队列
-(void)asyncMainQueue{
dispatch_queue_t main_queue = dispatch_get_main_queue();

for (int i = 0; i<5; i++) {
    dispatch_async(main_queue, ^{
        NSLog(@"i = %d",i);
        NSLog(@"current thread = %@",[NSThread currentThread]);
    });
}
for (int i = 0; i<5; i++) {
    NSLog(@"=%@",[NSThread currentThread]);
}
}
2016-11-07 13:39:55.601 gcd[5411:330259] =<NSThread: 0x60800006b2c0>{number = 1, name = main}
2016-11-07 13:39:55.602 gcd[5411:330259] =<NSThread: 0x60800006b2c0>{number = 1, name = main}
2016-11-07 13:39:55.603 gcd[5411:330259] =<NSThread: 0x60800006b2c0>{number = 1, name = main}
2016-11-07 13:39:55.603 gcd[5411:330259] =<NSThread: 0x60800006b2c0>{number = 1, name = main}
2016-11-07 13:39:55.604 gcd[5411:330259] =<NSThread: 0x60800006b2c0>{number = 1, name = main}
2016-11-07 13:39:55.611 gcd[5411:330259] i = 0
2016-11-07 13:39:55.611 gcd[5411:330259] current thread = <NSThread: 0x60800006b2c0>{number = 1, name = main}
2016-11-07 13:39:55.612 gcd[5411:330259] i = 1
2016-11-07 13:39:55.612 gcd[5411:330259] current thread = <NSThread: 0x60800006b2c0>{number = 1, name = main}
2016-11-07 13:39:55.612 gcd[5411:330259] i = 2
2016-11-07 13:39:55.613 gcd[5411:330259] current thread = <NSThread: 0x60800006b2c0>{number = 1, name = main}
2016-11-07 13:39:55.613 gcd[5411:330259] i = 3
2016-11-07 13:39:55.613 gcd[5411:330259] current thread = <NSThread: 0x60800006b2c0>{number = 1, name = main}
2016-11-07 13:39:55.614 gcd[5411:330259] i = 4
2016-11-07 13:39:55.726 gcd[5411:330259] current thread = <NSThread: 0x60800006b2c0>{number = 1, name = main}

异步主队列 分析
异步是不阻塞我们的当前线程(主线程) 所以下面for循环的 NSLog(@"=%@",[NSThread currentThread]);先被打印.async和main_queue组合没有创建新的线程 还是在当前线程中(主线程)这个时候当前线程(主线程)有下面的for循环打印任务 所以要等下面的任务打印好 上面的for循环 才会打印

// 异步 全局队列
-(void)asyncGlobleQueue{
dispatch_queue_t globle_queue = dispatch_get_global_queue(0, 0);

for (int i = 0; i<5; i++) {
    dispatch_async(globle_queue, ^{
        NSLog(@"i = %d",i);
        NSLog(@"current thread = %@",[NSThread currentThread]);
    });
}
for (int i = 0; i<5; i++) {
    NSLog(@"+++%@",[NSThread currentThread]);
}
}
2016-11-07 13:52:18.783 gcd[5479:341111] i = 4
2016-11-07 13:52:18.783 gcd[5479:341056] +++<NSThread: 0x6000000658c0>{number = 1, name = main}
2016-11-07 13:52:18.783 gcd[5479:341092] i = 1
2016-11-07 13:52:18.783 gcd[5479:341094] i = 3
2016-11-07 13:52:18.783 gcd[5479:341091] i = 2
2016-11-07 13:52:18.783 gcd[5479:341109] i = 0
2016-11-07 13:52:18.783 gcd[5479:341056] +++<NSThread: 0x6000000658c0>{number = 1, name = main}
2016-11-07 13:52:18.783 gcd[5479:341111] current thread = <NSThread: 0x60800006aac0>{number = 3, name = (null)}
2016-11-07 13:52:18.784 gcd[5479:341094] current thread = <NSThread: 0x60800006b500>{number = 5, name = (null)}
2016-11-07 13:52:18.784 gcd[5479:341092] current thread =  <NSThread: 0x600000071b00>{number = 4, name = (null)}
2016-11-07 13:52:18.784 gcd[5479:341091] current thread = <NSThread: 0x600000071980>{number = 6, name = (null)}
2016-11-07 13:52:18.784 gcd[5479:341056] +++<NSThread: 0x6000000658c0>{number = 1, name = main}
2016-11-07 13:52:18.784 gcd[5479:341109] current thread = <NSThread: 0x6000000719c0>{number = 7, name = (null)}
2016-11-07 13:52:18.784 gcd[5479:341056] +++<NSThread: 0x6000000658c0>{number = 1, name = main}
2016-11-07 13:52:18.793 gcd[5479:341056] +++<NSThread: 0x6000000658c0>{number = 1, name = main}

异步 全局队列分析
首先 异步 没有阻塞当前线程(主线程) 所以打印的第二行 就已经打印了我们下面的for循环了根据打印的log可以清楚的看到 async和globle_queue创建了新的线程 解释一下打印的顺序打印第一行
2016-11-07 13:52:18.783 gcd[5479:341111] i = 4 这个时候创建了新的线程(非主线程)是在新的线程中打印的,不阻塞当前线程(主线程)
2016-11-07 13:52:18.783 gcd[5479:341056] +++<NSThread: 0x6000000658c0>{number = 1, name = main}就是在当前线程打印的上面开辟了一个新线程做他自己的事下面 当前线程 做自己的事 想象一下就是第一个for循环一下就走完了没循环一次(就可能)创建一个线程就结束循环了打印就是在这创建的各个线程中异步打印..所以上面 for循环的顺序和下面的就乱了

//异步 穿行队列
-(void)asyncSerialQueue{
dispatch_queue_t serial_queue = dispatch_queue_create("com.rea", DISPATCH_QUEUE_SERIAL);

for (int i = 0; i<10; i++) {
    dispatch_async(serial_queue, ^{
        NSLog(@"---i = %d",i);
        NSLog(@"current thread = %@",[NSThread currentThread]);
    });
}

for (int i = 0; i<5; i++) {
    NSLog(@"+++%@",[NSThread currentThread]);
}
}

2016-11-07 14:19:17.060 gcd[5549:360426] +++<NSThread: 0x608000066280>{number = 1, name = main}
2016-11-07 14:19:17.060 gcd[5549:360461] ---i = 0
2016-11-07 14:19:17.061 gcd[5549:360426] +++<NSThread: 0x608000066280>{number = 1, name = main}
2016-11-07 14:19:17.061 gcd[5549:360461] current thread = <NSThread: 0x600000071080>{number = 3, name = (null)}
2016-11-07 14:19:17.062 gcd[5549:360426] +++<NSThread: 0x608000066280>{number = 1, name = main}
2016-11-07 14:19:17.062 gcd[5549:360461] ---i = 1
2016-11-07 14:19:17.062 gcd[5549:360426] +++<NSThread: 0x608000066280>{number = 1, name = main}
2016-11-07 14:19:17.062 gcd[5549:360461] current thread = <NSThread: 0x600000071080>{number = 3, name = (null)}
2016-11-07 14:19:17.062 gcd[5549:360426] +++<NSThread: 0x608000066280>{number = 1, name = main}
2016-11-07 14:19:17.062 gcd[5549:360461] ---i = 2
2016-11-07 14:19:17.062 gcd[5549:360461] current thread = <NSThread: 0x600000071080>{number = 3, name = (null)}
2016-11-07 14:19:17.062 gcd[5549:360461] ---i = 3
2016-11-07 14:19:17.062 gcd[5549:360461] current thread = <NSThread: 0x600000071080>{number = 3, name = (null)}
2016-11-07 14:19:17.063 gcd[5549:360461] ---i = 4
2016-11-07 14:19:17.078 gcd[5549:360461] current thread = <NSThread: 0x600000071080>{number = 3, name = (null)}
2016-11-07 14:19:17.078 gcd[5549:360461] ---i = 5
2016-11-07 14:19:17.078 gcd[5549:360461] current thread = <NSThread: 0x600000071080>{number = 3, name = (null)}
2016-11-07 14:19:17.078 gcd[5549:360461] ---i = 6
2016-11-07 14:19:17.078 gcd[5549:360461] current thread = <NSThread: 0x600000071080>{number = 3, name = (null)}
2016-11-07 14:19:17.078 gcd[5549:360461] ---i = 7
2016-11-07 14:19:17.079 gcd[5549:360461] current thread = <NSThread: 0x600000071080>{number = 3, name = (null)}
2016-11-07 14:19:17.079 gcd[5549:360461] ---i = 8
2016-11-07 14:19:17.079 gcd[5549:360461] current thread = <NSThread: 0x600000071080>{number = 3, name = (null)}
2016-11-07 14:19:17.079 gcd[5549:360461] ---i = 9
2016-11-07 14:19:17.080 gcd[5549:360461] current thread = <NSThread: 0x600000071080>{number = 3, name = (null)}

异步 穿行队列分析
异步 不会阻塞当前线程 所以第一行打印的是下面的for循环
2016-11-07 14:19:17.060 gcd[5549:360426] +++<NSThread: 0x608000066280>{number = 1, name = main}
async 和serial_queue组合会创建新的线程 但是只会创建一个线程 各个线程做各个的事情 打印就是各打印各的. 异步 穿行只会创建一个线程 在这个所以这个 异步串行是 有顺序的额

// 异步 并行
-(void)asyncConcurrentQueue{
dispatch_queue_t concurrent_queue = dispatch_queue_create("lccc", DISPATCH_QUEUE_CONCURRENT);

for (int i = 0; i<10; i++) {
    dispatch_async(concurrent_queue, ^{
        NSLog(@"i = %d",i);
        NSLog(@"current thread = %@",[NSThread currentThread]);
    });
}
for (int i = 0; i<5; i++) {
    NSLog(@"+++%@",[NSThread currentThread]);
}}

2016-11-07 14:30:55.875 gcd[5596:370161] i = 2
2016-11-07 14:30:55.875 gcd[5596:370159] i = 1
2016-11-07 14:30:55.875 gcd[5596:370127] +++<NSThread: 0x608000076180>{number = 1, name = main}
2016-11-07 14:30:55.875 gcd[5596:370174] i = 0
2016-11-07 14:30:55.876 gcd[5596:370177] i = 5
2016-11-07 14:30:55.876 gcd[5596:370176] i = 4
2016-11-07 14:30:55.875 gcd[5596:370158] i = 3
2016-11-07 14:30:55.876 gcd[5596:370159] current thread = <NSThread: 0x608000263300>{number = 4, name = (null)}
2016-11-07 14:30:55.876 gcd[5596:370127] +++<NSThread: 0x608000076180>{number = 1, name = main}
2016-11-07 14:30:55.876 gcd[5596:370178] i = 6
2016-11-07 14:30:55.876 gcd[5596:370161] current thread = <NSThread: 0x60000007abc0>{number = 3, name = (null)}
2016-11-07 14:30:55.876 gcd[5596:370177] current thread = <NSThread: 0x608000263240>{number = 6, name = (null)}
2016-11-07 14:30:55.876 gcd[5596:370174] current thread = <NSThread: 0x60000007a3c0>{number = 5, name = (null)}
2016-11-07 14:30:55.877 gcd[5596:370179] i = 7
2016-11-07 14:30:55.877 gcd[5596:370158] current thread = <NSThread: 0x608000263380>{number = 8, name = (null)}
2016-11-07 14:30:55.877 gcd[5596:370127] +++<NSThread: 0x608000076180>{number = 1, name = main}
2016-11-07 14:30:55.877 gcd[5596:370180] i = 8
2016-11-07 14:30:55.877 gcd[5596:370159] i = 9
2016-11-07 14:30:55.877 gcd[5596:370176] current thread = <NSThread: 0x608000263280>{number = 7, name = (null)}
2016-11-07 14:30:55.877 gcd[5596:370178] current thread = <NSThread: 0x608000263140>{number = 9, name = (null)}
2016-11-07 14:30:55.877 gcd[5596:370179] current thread = <NSThread: 0x60000007ae80>{number = 10, name = (null)}
2016-11-07 14:30:55.884 gcd[5596:370127] +++<NSThread: 0x608000076180>{number = 1, name = main}
2016-11-07 14:30:55.884 gcd[5596:370180] current thread = <NSThread: 0x6080002631c0>{number = 11, name = (null)}
2016-11-07 14:30:55.884 gcd[5596:370159] current thread = <NSThread: 0x608000263300>{number = 4, name = (null)}
2016-11-07 14:30:55.885 gcd[5596:370127] +++<NSThread: 0x608000076180>{number = 1, name = main}

异步 并行队列分析
貌似和异步 globle队列是一样的....

====================================================================================================
异步的说完了 现在说一下同步
1 同步 mainQueue
2同步 globleQueue
3同步 serialQueue
3同步 concurrentQueue
第一种 我会在下一篇 单独讨论 下面三种简单说一下如图下图


EE9372F8-FA11-490B-A269-DB9481BE1BB6.png

同步的意思是 (不创建线程) 重点哦 当前在神马线程那么block代码块里面就会在 神马线程 并且同步会立马回调 重点哦立马回调
所以 如图所示 for循环所在的线程 是主线程 那么block里面肯定 也是 主线程 下面for 循环也是 主线程 记住同步 会立马回调 并且block里和 下面的for循环 都是zai 一个线程 在任何(一个)线程中做任务 那么都是 有先后顺序的. 所以fou循环 运行的如图 164 行就会 立马回调 打印block里面的 知道fou循环 结束 再 打印下面for循环的 ...

打印效果是这样的


A7F3A549-FAC5-403C-BBCE-45A5BEE83EF7.png

希望我说明白了

上一篇下一篇

猜你喜欢

热点阅读