多线程相关

1.GCD

  • 同步/异步和串行/并发
  • dispatch_barrier_async
  • dispatch_group
(1)同步/异步和串行/并发
  • dispatch_sync(serial_queue, ^{//任务});
  • dispatch_async(serial_queue,^{//任务});
  • dispatch_sync(concurrent_queue,^{//任务});
  • dispatch_async(concurrent_queue,^{//任务});
    同步串行
      - (void)viewDidLoad {
         [super viewDidLoad];
         dispatch_sync(dispatch_get_main_queue(), ^{
            [self doSomething];
        });
     }
    
    上面代码会产生死锁,产生死锁的原因是,队列引起的循环等待。
    截图1.png
- (void)viewDidLoad {
    [super viewDidLoad];
     dispatch_sync(serialQueue, ^{
        [self doSomething];
    });
}

上面的代码是没有问题的

截图2.png

同步并发

- (void)viewDidLoad {
    NSLog(@"1");
    dispatch_sync(global_queue(), ^{
        NSLog(@"2");
        dispatch_sync(global_queue(), ^{
             NSLog(@"3");
        });
        NSLog(@"4");
    });
    NSLog(@"5");
}
打印结果:12345

异步串行

- (void)viewDidLoad {
        [super viewDidLoad];
        dispatch_async(dispatch_get_main_queue(), ^{
          [self doSomething];
       });
 }

异步并发

   - (void)viewDidLoad {
     dispatch_async(global_queue,^{
        NSLog(@"1");
       [self performSelector:@selector(printLog) 
                         withObject:nil  
                          afterDelay:0];
          NSLog(@"3");
    })
  }
  - (void)printLog {
        NSLog(@"2");
  }
  打印结果: 13

2.dispatch_barrier_async()

(1)怎样利用GCD实现多读单写?
截图1.png

截图2.png

dispatch_barrier_async(concurrent_queue,^{//写操作});

#import 
@interface UserCenter : NSObject
- (id)objectForKey:(NSString *)key;
- (void)setObject:(id)obj forKey:(NSString *)key;
@end

#import "UserCenter.h"

@interface UserCenter()
{
    dispatch_queue_t  concurrent_queue;
    NSMutableDictionary *userCenterDic;
}
@end

@implementation UserCenter

- (instancetype)init{
    self = [super init];
    if (self) {
        // 通过宏定义DISPATCH_QUEUE_CONCURRENT 创建一个并发队列
        concurrent_queue = dispatch_queue_create("read_write_queue", DISPATCH_QUEUE_CONCURRENT);
        // 创建数据库容器
        userCenterDic = [NSMutableDictionary dictionary];
    }
    return self;
}

- (id)objectForKey:(NSString *)key{
    __block id obj;
    //同步读取指定数据
    dispatch_sync(concurrent_queue, ^{
        obj = [userCenterDic objectForKey:key];
    });
    return obj;
}

- (void)setObject:(id)obj forKey:(NSString *)key{
    // 异步栅栏调用设置数据
    dispatch_barrier_async(concurrent_queue, ^{
        [userCenterDic setObject:obj forKey:key];
    });
}

@end

3.dispatch_group_async()

使用GCD实现这个需求:A、B、C三个任务并发,完成后执行任务D?


截图3.png
#import 

@interface GroupObject : NSObject

- (void)handle;

@end

#import "GroupObject.h"

@interface GroupObject()
{
    dispatch_queue_t concurrent_queue;
    NSMutableArray  *arrayURLs;
}
@end

@implementation GroupObject

- (instancetype)init
{
    
    self = [super init];
    if (self) {
        //创建并发队列
        concurrent_queue = dispatch_queue_create("concurrent_queue",DISPATCH_QUEUE_CONCURRENT);
        arrayURLs = [NSMutableArray array];
    }
    return self;
}

- (void)handle{
    //创建一个group
    dispatch_group_t group = dispatch_group_create();
    // for循环遍历各个元素
    for (NSURL *url in arrayURLs) {
        //异步组分派到并发队列当中
        dispatch_group_async(group, concurrent_queue, ^{
            //根据url去下载图片
            NSLog(@"%@",url);
        });
    }
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        //当添加到数组中的所有任务执行完成之后会调用该block
        NSLog(@"所有图片下载完成");
    });
}
@end

4.NSOperation

需要和NSOperationQueue配合使用来实现多线程方案

  • 添加任务依赖
  • 任务执行状态控制
  • 最大并发量
(1)任务执行状态控制
  • isReady 当前任务是否处于就绪状态
  • isExecuting 当前任务是否处于执行中的状态
  • isFinished 当前任务是否已经执行完成
  • isCancelled 当前任务是否已取消

如果只重写main方法,底层控制变更任务执行状态,以及任务退出。
如果重写了start方法,自行控制任务状态。

你可能感兴趣的:(多线程相关)