//多线程
//进程和线程的区别
//一个应用在计算机里代表一个进程,一个应用中执行的一个任务,一个操作代表的是一个线程
//一个进程可以有多个线程
//线程分为主线程和子线程
//三种多线程
//NSThread
//NSOperation
//GCD(grand central dispatch)
//最常用,最强大的是GCD,从IOS4.0的时候就有GCD,已经到现在9.0,很成熟,节省资源,使用起来非常方便,效率高
}
- (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
- (IBAction)NSThreadButton:(UIButton *)sender {
//NSThread创建多线程
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(cycle) object:nil];
//执行子线程
[thread start];
/*
myView *aView = [[myView alloc] initWithFrame:...];
[aView addMyTarget:self Action:@select(aViewAction)];
-(void)addMyTarget:(id)target Action:(SEL)action
{
self.myTarget = target;
self.myAction = action;
}
-(void)touchBegin:
{
[self.myTarget performSelec...action];
}
*/
[NSThread detachNewThreadSelector:@selector(downLoadImage) toTarget:self withObject:nil];
}
-(void)downLoadImage
{
NSString *str = @"http://img4.duitang.com/uploads/item/201207/28/20120728105310_jvAjW.thumb.600_0.jpeg";
NSURL *url = [NSURL URLWithString:str];
NSData *data = [NSData dataWithContentsOfURL:url];
//self.myImageView.image = [UIImage imageWithData:data];
self.myImageView.backgroundColor = [UIColor lightGrayColor];
NSLog(@"%@ %d", [NSThread currentThread], [NSThread isMainThread]);
//回到主线程
[self performSelector:@selector(goMainThread:) onThread:[NSThread mainThread] withObject:data waitUntilDone:YES];
}
//数据的刷新最好在主线程
-(void)goMainThread:(NSData *)data
{
NSLog(@"========当前线程为:%@ 是否是主线程:%d",[NSThread currentThread], [NSThread isMainThread]);
self.myImageView.image = [UIImage imageWithData:data];
}
-(void)cycle
{
for (int i = 0; i < 100; i++)
{
NSLog(@"i = %d", i);
}
}
- (IBAction)NSOperationButton:(UIButton *)sender {
//NSOperation 是一个抽象类,它提供了两个子类来创建子线程
//子类1
NSInvocationOperation *invocation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(downLoadImage) object:nil];
NSInvocationOperation *invocation2 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(cycle) object:nil];
//子类2
NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
for (int i = 0; i < 100; i++)
{
NSLog(@"block i = %d", i);
}
}];
//创建线程队列
NSOperationQueue *queue = [[NSOperationQueue alloc] init];
//设置最大的队列数 不设置则有几个子线程就有几个队列
[queue setMaxConcurrentOperationCount:2];
//设置队列等待 前者等待后者 后者执行完再执行前者
[invocation addDependency:blockOperation];
//将三个人物添加到子线程队列中
[queue addOperation:invocation];
[queue addOperation:invocation2];
[queue addOperation:blockOperation];
}
//GCD多线程两种方法:1.串行队列 2.并行队列
//串行队列特点:任务是一个一个的执行,当一个任务执行完毕再执行另一个,多个任务不是同事进行,而是一个一个执行
//并行队列特点:多个任务可以同时执行,谁先完成任务不一定,提供任务执行效率,是工作中常用的一种方式
//串行队列的使用:
//1.创建主线程队列
dispatch_queue_t mainQueue = dispatch_get_main_queue();
//将任务放在队列中执行
dispatch_async(mainQueue, ^{
NSLog(@"是否是主线程1==%d", [NSThread isMainThread]);
});
dispatch_async(mainQueue, ^{
NSLog(@"是否是主线程2==%d", [NSThread isMainThread]);
});
dispatch_async(mainQueue, ^{
NSLog(@"是否是主线程3==%d", [NSThread isMainThread]);
});
dispatch_async(mainQueue, ^{
NSLog(@"是否是主线程4==%d", [NSThread isMainThread]);
});
//自定义串行队列
//参数1.队列标识符,通常以公司逆向域名形式
//参数2.队列方式DISPATCH_QUEUE_SERIAL是串行队列类型
dispatch_queue_t serialQueue = dispatch_queue_create("com.lanou3g.CGD.Serial", DISPATCH_QUEUE_SERIAL);
dispatch_async(serialQueue, ^{
NSLog(@"是否是主线程1==%d", [NSThread isMainThread]);
});
dispatch_async(serialQueue, ^{
NSLog(@"是否是主线程2==%d", [NSThread isMainThread]);
});
dispatch_async(serialQueue, ^{
NSLog(@"是否是主线程3==%d", [NSThread isMainThread]);
});
dispatch_async(serialQueue, ^{
NSLog(@"是否是主线程4==%d", [NSThread isMainThread]);
});
//系统的并行队列
//参数1.并行duil执行优先级
//参数2.备用参数设置为0
dispatch_queue_t globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(globalQueue, ^{
NSLog(@"是否是主线程1==%d", [NSThread isMainThread]);
});
dispatch_async(globalQueue, ^{
NSLog(@"是否是主线程2==%d", [NSThread isMainThread]);
});
dispatch_async(globalQueue, ^{
NSLog(@"是否是主线程3==%d", [NSThread isMainThread]);
});
dispatch_async(globalQueue, ^{
NSLog(@"是否是主线程4==%d", [NSThread isMainThread]);
});
//自定义并行队列 CONCURRENT并行
//参数1.队列标识符
//参数2.队列类型
dispatch_queue_t conCurrentQueue = dispatch_queue_create("com.lanou3g.GCD.ConCurrent", DISPATCH_QUEUE_CONCURRENT);
dispatch_async(conCurrentQueue, ^{
NSLog(@"是否是主线程1==%d", [NSThread isMainThread]);
});
dispatch_async(conCurrentQueue, ^{
NSLog(@"是否是主线程2==%d", [NSThread isMainThread]);
});
dispatch_async(conCurrentQueue, ^{
NSLog(@"是否是主线程3==%d", [NSThread isMainThread]);
});
dispatch_async(conCurrentQueue, ^{
NSLog(@"是否是主线程4==%d", [NSThread isMainThread]);
});
//http://img4.duitang.com/uploads/item/201207/28/20120728105310_jvAjW.thumb.600_0.jpeg
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSURL *url = [NSURL URLWithString:@"http://img4.duitang.com/uploads/item/201207/28/20120728105310_jvAjW.thumb.600_0.jpeg"];
NSData *data = [NSData dataWithContentsOfURL:url];
dispatch_async(dispatch_get_main_queue(), ^{
//回到主线程,刷新数据
self.aImageView.image = [UIImage imageWithData:data];
});
});
//延迟多少秒执行队列里的任务
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(3 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
NSLog(@"延迟三秒才打印");
});
//只执行一次
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSLog(@"只被打印一次");
});