关于多线程的使用属于重点掌握知识,今天总结一下自己已经学到的多线程使用方法。多线程使用方法现阶段主要使用了3种。1:GCD(个人觉得这个属于最常用方法,因为其贴近底层,执行效率更高) 2.
NSOperation(使用率较高,属于苹果封装好的GCD类,面向对象更好理解) 3.NSThread(个人使用较少,创建好对象后需要自己手动启动线程)
1.GCD
多条异步线程启用,此方法中首先创建一个异步队列,因为所有的线程都需要加入队列才能得到使用,然后创建4个子线程操作加入队列,这样异步线程开启,GCD会自动管理线程,我们只需要关心我们要做什么操作即可
1 - (void)demo1{
2 /** 优先级
3 * #define DISPATCH_QUEUE_PRIORITY_HIGH 2 优先
4 * #define DISPATCH_QUEUE_PRIORITY_DEFAULT 0 正常
5 * #define DISPATCH_QUEUE_PRIORITY_LOW (-2) 低
6 * #define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN 后台
7 */
8 //创建异步队列
9 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
10 //往队列里添加线程操作
11 dispatch_async(queue, ^{
12 NSLog(@"---下载图片1--%@",[NSThread currentThread]);
13 });
14 dispatch_async(queue, ^{
15 NSLog(@"---下载图片2--%@",[NSThread currentThread]);
16 });
17 dispatch_async(queue, ^{
18 NSLog(@"---下载图片3--%@",[NSThread currentThread]);
19 });
20 dispatch_async(queue, ^{
21 NSLog(@"---下载图片4--%@",[NSThread currentThread]);
22 });
23 }
从结果分析我们达到了多条线程异步下载的效果
异步串行队列
1 - (void)demo2{
2 /**
3 * 串行队列创建
4 * @param "Myqueue.test" 标识符
5 * @param NULL 一般为NULL
6 */
7 dispatch_queue_t queue = dispatch_queue_create("Myqueue.test", NULL);
8 //开启异步线程
9 dispatch_async(queue, ^{
10 NSLog(@"---下载图片1--%@",[NSThread currentThread]);
11 });
12 dispatch_async(queue, ^{
13 NSLog(@"---下载图片2--%@",[NSThread currentThread]);
14 });
15 dispatch_async(queue, ^{
16 NSLog(@"---下载图片3--%@",[NSThread currentThread]);
17 });
18 dispatch_async(queue, ^{
19 NSLog(@"---下载图片4--%@",[NSThread currentThread]);
20 });
21 }
从此结果分析,异步串行队列实质上只开辟一个子线程,并且按顺序执行之前自己添加的操作
异步组队列
1 - (void)demo3{
2 //设置异步队列
3 dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
4 //设置组队列
5 dispatch_group_t group = dispatch_group_create();
6 dispatch_group_async(group, queue, ^{
7 NSLog(@"---下载图片1--%@",[NSThread currentThread]);
8 });
9 dispatch_group_async(group, queue, ^{
10 NSLog(@"---下载图片2--%@",[NSThread currentThread]);
11 });
12 dispatch_group_async(group, queue, ^{
13 NSLog(@"---下载图片3--%@",[NSThread currentThread]);
14 });
15 dispatch_group_async(group, queue, ^{
16 NSLog(@"---下载图片4--%@",[NSThread currentThread]);
17 });
18 //组队列操作执行完成后调用
19 dispatch_group_notify(group, queue, ^{
20 NSLog(@"下载完成");
21 });
22 }
组队列操作的好处是让我们先执行某些操作 在操作执行完成后再执行什么操作。
2.NSOperation
NSOperation的使用一般都是基于其子类NSBlockOperation,使用方法如下
NSBlockOperation 使用
1 - (void)demo4{
2 //NSBlockOperation start使用方法
3 dispatch_async(dispatch_queue_create("123", NULL), ^{
4 NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
5 NSLog(@"---下载图片1--%@",[NSThread currentThread]);
6 }];
7 //增加额外线程 addExecutionBlock 额外线程是在operation1主线程执行后 再异步执行
8 [operation1 addExecutionBlock:^{
9 NSLog(@"---下载图片2--%@",[NSThread currentThread]);
10 }];
11 [operation1 addExecutionBlock:^{
12 NSLog(@"---下载图片3--%@",[NSThread currentThread]);
13 }];
14 [operation1 addExecutionBlock:^{
15 NSLog(@"---下载图片4--%@",[NSThread currentThread]);
16 }];
17 //用start 直接使用当前线程
18 [operation1 start];
19 });
20 }
增加的额外线程只会在其第一个操作执行完成后再异步执行。这样当多个操作都依赖于一个操作完成时执行,此方法比较适用
说完NSBlockOperation,必须提一下NSOperationQueue的使用,因为一般NSBlockOperation对象都是加入NSOperationQueue对象中使用,这样不用自己手动启动线程
1 - (void)demo5{
2 //创建异步队列
3 NSOperationQueue *queue = [[NSOperationQueue alloc] init];
4 //创建主线程队列
5 // NSOperationQueue *queue = [NSOperationQueue mainQueue];
6 //若为主线程 则相当于串行队列
7 [queue addOperationWithBlock:^{
8 NSLog(@"---下载图片1--%@",[NSThread currentThread]);
9 }];
10 [queue addOperationWithBlock:^{
11 NSLog(@"---下载图片2--%@",[NSThread currentThread]);
12 }];
13 //创建操作
14 NSBlockOperation *operation1 = [NSBlockOperation blockOperationWithBlock:^{
15 NSLog(@"---下载图片1--%@",[NSThread currentThread]);
16 }];
17 NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
18 NSLog(@"---下载图片2--%@",[NSThread currentThread]);
19 }];
20 NSBlockOperation *operation3 = [NSBlockOperation blockOperationWithBlock:^{
21 NSLog(@"---下载图片3--%@",[NSThread currentThread]);
22 }];
23 NSBlockOperation *operation4 = [NSBlockOperation blockOperationWithBlock:^{
24 NSLog(@"---下载图片4--%@",[NSThread currentThread]);
25 }];
26 //将操作添加进队列
27 [queue addOperation:operation1];
28 [queue addOperation:operation2];
29 [queue addOperation:operation3];
30 [queue addOperation:operation4];
31 }
队列中所有操作都异步执行,其中
[queue addOperationWithBlock:^{
NSLog(@"---A--%@",[NSThread currentThread]);
}];
相当于
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
NSLog(@"---A--%@",[NSThread currentThread]);
}];
[queue addOperation:operation];
这种写法方便了程序员编写代码,达到代码简化的效果,此处主队列串行的结果图就不上传了
异步队列依赖关系设置(达到上述GCD中组队列效果)
1 - (void)demo7{
2 //创建异步队列
3 NSOperationQueue *queue = [[NSOperationQueue alloc] init];
4 //创建操作
5 NSBlockOperation *operationA = [NSBlockOperation blockOperationWithBlock:^{
6 NSLog(@"-----A------");
7 }];
8 NSBlockOperation *operationB = [NSBlockOperation blockOperationWithBlock:^{
9 NSLog(@"-----B------");
10 }];
11 NSBlockOperation *operationC = [NSBlockOperation blockOperationWithBlock:^{
12 NSLog(@"-----C------");
13 }];
14 //设置依赖关系 不能相互依赖
15 [operationB addDependency:operationA];
16 [operationC addDependency:operationA];
17 //将操作写进队列
18 [queue addOperation:operationA];
19 [queue addOperation:operationB];
20 [queue addOperation:operationC];
21 }
此处运行了2次demo,可以发现 B、C都是在A完成后才进行的操作。达到了依赖效果。
关于NSThread此处就不提了,因为其使用率较低,掌握好上述2中就能做好多线程开发。
如文中有何错误,希望大家指出!