iOS多线程备忘

Author Avatar
新风作浪 5月 26, 2016
  • 在其它设备中阅读本文章

进程与线程

进程: 启动Chrome浏览器,就是启动一个进程

线程:使用Chrome一遍下载一遍浏览网页,这个时候有多个线程,下载的线程和加载网页的线程.

一个进程至少有一个线程,线程在进程中执行。线程中串行执行任务,同一时间只能执行一个任务。

NSThread

开启一个线程进行任务处理

1
2
3
4
5
6
[NSThread detachNewThreadSelector:@selector(dosomething) toTarget:self withObject:nil];
[NSThread detachNewThreadWithBlock:^{
[self dosomething];
}];
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(dosomething) object:nil];
[thread start];

NSObject类拓展直接使用

1
2
3
[self performSelectorInBackground:@selector(dosomething) withObject:nil];
[self performSelectorOnMainThread:@selector(dosomething) withObject:nil waitUntilDone:NO];
[self performSelector:@selector(dosomething) withObject:nil];

创建一个异步任务在后台执行,然后在主线程更新UI操作

1
2
3
4
5
6
7
8
9
10
11
12
13
[self performSelectorInBackground:@selector(requestData:) withObject:@"https://xxx.png"];
- (void)requestData:(NSString *)urlString
{
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlString]];
[self performSelectorOnMainThread:@selector(updateUI:) withObject:data waitUntilDone:NO];
}
- (void)updateUI:(NSData *)data
{
// 拿到data,跟新UI
}

NSOperation、NSOperationQueue

Grand Centeral Dispatch

并行与串行

dispatch_get_global_queue 全局并行队列
dispatch_get_main_queue 主线程串行队列

dispatch_sync(xxx, ^{ }) 同步线程
dispatch_async(xxx, ^{ }) 异步线程

搭配使用

1
2
3
4
5
6
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
// 子线程中耗时操作
dispatch_async(dispatch_get_main_queue(), ^{
// 主线程中更新页面
});
});

GCD单例

1
2
3
4
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
});

执行一次,常用来写单例方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
+ (id)sharedManager {
static dispatch_once_t once;
static id instance;
dispatch_once(&once, ^{
instance = [[self alloc] init];
});
return instance;
}

GCD定时器

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
__block int timeout = 3;
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0,queue);
dispatch_source_set_timer(timer,dispatch_walltime(NULL, 0),1.0*NSEC_PER_SEC, 0); //每秒执行
dispatch_source_set_event_handler(timer, ^{
if(timeout<=0){ //倒计时结束,关闭
dispatch_async(dispatch_get_main_queue(), ^{
});
}else{
dispatch_async(dispatch_get_main_queue(), ^{
});
timeout--;
}
});
dispatch_resume(timer);

dispatch_after延后执行

1
2
3
4
5
double delayInSeconds = 2.0;
dispatch_time_t popTime = dispatch_time(DISPATCH_TIME_NOW, (int64_t) (delayInSeconds * NSEC_PER_SEC));
dispatch_after(popTime, dispatch_get_main_queue(), ^(void){
// 两秒后执行
});

Dispatch Group

有时候一个页面需要发多个请求,待所以请求完毕,再去更新数据

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
dispatch_queue_t queue = dispatch_queue_create(DISPATCH_QUEUE_PRIORITY_DEFAULT,0);
dispatch_group_t group = dispatch_group_create();
dispatch_group_async(group, queue, ^{
NSLog(@"111");
});
dispatch_group_async(group, queue, ^{
NSLog(@"222");
});
dispatch_group_async(group, queue, ^{
NSLog(@"333");
});
dispatch_group_notify(group, dispatch_get_main_queue(), ^{
NSLog(@"done");
});
/* dispatch_group_notify 也可以换成下面dispatch_group_wait 等待上面执行完毕再往下执行*/
//dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
//NSLog(@"done");