iOS 开发 Objective-C

第九篇:Objective-C 知识回顾多线程

2019-11-20  本文已影响0人  望穿秋水小作坊
多线程大纲

9.1.同步/异步 和 串行/并发

问题一:同步/异步 和 串行/并发组合有哪些?
问题二:分析下面代码是否存在问题?
- (void)viewDidLoad {
    [super viewDidLoad];
    dispatch_sync(dispatch_get_main_queue(), ^{
        NSLog(@"Hello world!");
    });
}
问题三:分析下面代码是否存在问题?
- (void)viewDidLoad {
    [super viewDidLoad];
    dispatch_queue_t serialQueue = dispatch_queue_create("apple.searial", DISPATCH_QUEUE_SERIAL);
    dispatch_sync(serialQueue, ^{
        NSLog(@"Hello world!");
    });
}
问题四:分析下面代码是输出是什么?
- (void)viewDidLoad {
    [super viewDidLoad];
    NSLog(@"1");
    dispatch_sync(dispatch_get_global_queue(0, 0), ^{
        NSLog(@"2");
        dispatch_sync(dispatch_get_global_queue(0, 0), ^{
            NSLog(@"3");
        });
        NSLog(@"4");
    });
    NSLog(@"5");
}

问题五:下面代码熟悉吗?
    dispatch_async(dispatch_get_main_queue(), ^{
        NSLog(@"这是我们开发中最常用的写法");
    });
问题五:分析下面代码是输出是什么?
- (void)viewDidLoad {
    [super viewDidLoad];
    dispatch_async(dispatch_get_global_queue(0, 0), ^{
        NSLog(@"1");
        [self performSelector:@selector(printLog) withObject:nil afterDelay:0];
        NSLog(@"3");
    });
}

- (void)printLog {
    NSLog(@"2"); 
}

9.2.dispatch_barrier_async()

问题一:怎么利用 GCD 实现多读单写?
流程分析
@implementation GlobalUserInfo

+ (GlobalUserInfo*) shareUserInfo {
    static GlobalUserInfo *instance;
    static dispatch_once_t onceToken;
    dispatch_once(&onceToken, ^{
        instance = [[self alloc] init];
    });
    return instance;
}

- (instancetype)init
{
    self = [super init];
    if (self) {
        concurrentQueue = dispatch_queue_create("userinfo_read_write", DISPATCH_QUEUE_CONCURRENT);
        userInfoDictionary = [[NSMutableDictionary alloc] init];
        // 假设对年龄这个数据的多读单写
        [userInfoDictionary setValue:@(1) forKey:@"age"];
    }
    return self;
}

- (int)getAge {
    __block id obj;
    // 同步读取指定数据
    dispatch_sync(concurrentQueue, ^{
        obj = [userInfoDictionary objectForKey:@"age"];
    });
    return [obj intValue];
}
- (void)setAge:(int)age {
    // 异步栅栏调用设置数据
    dispatch_barrier_async(concurrentQueue, ^{
        [self->userInfoDictionary setValue:@(age) forKey:@"age"];
        // 模拟耗时的写操作,才能看到效果
        [NSThread sleepForTimeInterval:2.0];
        NSLog(@"write queue4 %i", age);
    });
}
@end

9.3.dispatch_group_async()

问题一:怎么利用 GCD 实现这个需求:A、B、C 三个任务并发,完成后执行任务 D?
- (void)learnGCDGroup {
    // 模拟真实开发中多个数据资源需要下载
    NSMutableArray *urlArray = [[NSMutableArray alloc] init];
    for (int i = 0 ; i < 10; i++) {
        [urlArray addObject:@(i)];
    }
    
    // 创建一个group
    dispatch_group_t group = dispatch_group_create();
    
    // 创建一个并发队列
    dispatch_queue_t concurrentQueue = dispatch_queue_create("download_concurrent_queue", DISPATCH_QUEUE_CONCURRENT);
    
    // 进行并发图片下载
    for (id obj in urlArray) {
        // 模拟耗时下载
        dispatch_group_async(group, concurrentQueue, ^{
            int randomTime = arc4random()% 3;
            [NSThread sleepForTimeInterval:randomTime];
            NSLog(@"download resource finished %@",obj);
        });
    }
    dispatch_group_notify(group, dispatch_get_main_queue(), ^{
        NSLog(@"所有资源已经下载完毕,可以再主线程更新 UI 了.");
    });
}

9.4.NSOperationQueue

问题一:哪些特点的方法使用 NSOperation 更为方便呢?
问题二:我们可以控制 NSOperation 的哪些状态?
问题三:从代码的角度,我们如何控制 NSoperation 的状态?
问题四:系统是怎样移除一个 isFinished=YES 的 NSOperation 的?

9.6.多线程 和 锁

问题一:在 iOS 当中有哪些锁呢?或者说你使用过哪些锁?
上一篇 下一篇

猜你喜欢

热点阅读