2014年11月8日 上海 杨树浦路 小雨
下午,复习多线程
iOS多线程的实现方法有4种
1.系统自带
系统自带多线程使用只有一句代码,将任务放到后台运行。
[self performSelectorInBackground:@selector(task1) withObject:nil];
2.NSThread
NSThread的使用有两种
1. 创建对象,对象必须调用 start 方法调用
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(task1) object:nil];
[thread start];
2.类方法调用
[NSThread detachNewThreadSelector:@selector(task1) toTarget:self withObject:nil];
3.NSOperation
1.和 NSThread 类似,使用对象方法,必须调用 start 方法调用
NSInvocationOperation *io1 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(task1) object:nil];
[io1 start];
2.放到 NSOperation 线程
NSOperationQueue *oq = [[NSOperationQueue alloc] init];
[oq addOperation:io1];
可以给进程队列中的任务开始前添加一些操作
[oq addOperationWithBlock:^{
NSLog(@"任务开始");<span style="white-space:pre"> </span>// 任务开始前先执行
}];
4.GCD
GCD 必须熟练掌握
- (void)gcd
{
// 创建线程队列
/**
* 创建一个线程队列类型
*
* @param "chenbing" 队列名称,用于标识
* @param DISPATCH_QUEUE_CONCURRENT 并行队列(异步队列)
DISPATCH_QUEUE_SERIAL 串行队列(同步队列)(默认)
*
*/
dispatch_queue_t qt = dispatch_queue_create("chenbing", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(qt, ^{
[self task1];
});
dispatch_async(qt, ^{
[self task2];
});
dispatch_async(qt, ^{
[self task3];
});
/**
* dispatch_sync 队列任务增加方法为同步,不管创建的队列时同步还是异步,都是以同步执行,(即一个任务完成,再执行第二个任务)
*
* dispatch_async 队列任务增加方法为异步,但是要看队列类型为同步还是异步,如果队列类型为同步,则任务还是以同步执行。
*
* 同步运行所有任务的情况:队列为同步队列,或者任务是同步加到队列中的
*/
/**
* 一般使用系统自带队列
*
* 系统自带队列有多少个!!
5个, 一个主线程队列,4个对应不同优先级的全局异步队列
#define DISPATCH_QUEUE_PRIORITY_HIGH 2
#define DISPATCH_QUEUE_PRIORITY_DEFAULT 0
#define DISPATCH_QUEUE_PRIORITY_LOW (-2)
#define DISPATCH_QUEUE_PRIORITY_BACKGROUND INT16_MIN
typedef long dispatch_queue_priority_t;
// 获取默认优先级的全局并发dispatch queue
dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
第一个参数用于指定优先级,分别使用DISPATCH_QUEUE_PRIORITY_HIGH和DISPATCH_QUEUE_PRIORITY_LOW两个常量来获取高和低优先级的两个queue;第二个参数目前未使用到,默认0即可
*/
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
[self task1];
});
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[self task2];
});
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[self task3];
});
// 标准用法
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"子线程开始");
// 在子类写子线程的内容,在这里做子线程的任务
NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:@"http://image16-c.poco.cn/mypoco/myphoto/20140605/18/17457026820140605181136033_640.jpg?570x300_120"]];
dispatch_async(dispatch_get_main_queue(), ^{
NSLog(@"主线程开始");
// 任务完成后,回到主线程队列,进行UI刷新
UIImage *img = [UIImage imageWithData:data];
UIImageView *imgView = [[UIImageView alloc] initWithFrame:CGRectMake(0, 0, 320, 480)];
imgView.image = img;
[self.view addSubview:imgView];
});
});
}
- (void)gcdGroup
{
// 线程组:在线程组内所有的任务完成后,执行其他任务
// 组会监测所有任务的完成状态
// 创建一个线程组
dispatch_group_t gt = dispatch_group_create();
// 创建一个线程队列
dispatch_queue_t qt = dispatch_queue_create("chen", DISPATCH_QUEUE_CONCURRENT);
// 将任务放到线程队列中执行,同时放到线程组中管理
dispatch_group_async(gt, qt, ^{
[self task1];
});
dispatch_async(qt, ^{
sleep(5);
NSLog(@"taskAdd--->%@", [NSDate date]);
});
dispatch_group_async(gt, qt, ^{
[self task2];
});
dispatch_group_async(gt, qt, ^{
[self task3];
});
// 监测gt线程组中的任务,完成后,执行这个任务,并将此任务放到qt线程队列中
dispatch_group_notify(gt, qt, ^{
NSLog(@"所有任务执行完成");
NSLog(@"task----%@",[NSDate date]);
});
}
- (void)barrier
{
// 分组运行,需要中断,即在这个段的前面为一组任务,中断点后面也是一组任务
// 条件必须创建 DISPATCH_QUEUE_CONCURRENT 并行(异步)类型的线程队列
dispatch_queue_t qt = dispatch_queue_create("chen", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(qt, ^{
[self task1];
});
dispatch_async(qt, ^{
[self task2];
});
// 在所有任务中间中断,执行其他任务
dispatch_barrier_async(qt, ^{
NSLog(@"中断---->%@", [NSDate date]);
});
dispatch_async(qt, ^{
[self task3];
});
dispatch_async(qt, ^{
[self task1];
});
}
- (void)time
{
/**
* 时间
*
* @param DISPATCH_TIME_NOW 当前时间
* @param NSEC_PER_SEC 距离当前时间点时间点
*
*/
dispatch_time_t time = dispatch_time(DISPATCH_TIME_NOW, 3ull* NSEC_PER_SEC );
// 创建一个线程,并让其在固定的时间后执行
dispatch_after(time, dispatch_get_main_queue(), ^{
self.view.backgroundColor = [UIColor blueColor];
});
}