一、GCD(可以参考自己项目:61天-数据库网络--多线程之GCD)
1:GCD其实就是线程池技术,因为创建线程会消耗计算机的资源,所以GCD就是提前创建好一些线程形成一个线程池,然后当我们需要使用时,就把代码注入到已经创建好的线程池中的空闲线程中。
2:GCD会使用到块,因为假如我们有五个线程要想运行同一块代码,那么这五个线程就要调用同一个块,该块包括同一块代码。而块其实类似一个匿名的C语言中的函数。它的定义如下:
block 块的模式
返回值(^快的名字)(参数列表) = ^(实际的参数列表){
块的主体
}
3:在块的使用,块中是可以直接访问块外的变量,但是不能直接修改。如果要在块内修改变量,那么该变量是需要这样定义的: __block int num =123;,并且还需要调用块名,才可以使用块。
//1---定义一个无返回值的快
__blockint num =123;
void (^myblock)(void)=^
{
NSLog(@"num = %d", num--);
};
//必须调用块
myblock();
2---定义一个有返回值的快
int (^sum)(int)=^(int n)
{
int s = 0;
for (int i = 1; i<= n; i++) {
s+=i;
}
return s;
};
//调用块并且传参
int n = sum(100);
NSLog(@"%d",n);
一、生成GCD
GCD中需要注意的是:
1:使用dispatch_get_global_queue(0, 0)获得全局队列,第一个0指的是标示,第二个0指的是一种标志。这是一种固定的写法.后面是一个匿名块
2:因为想在非主线程中修改UI控件,那么就需要调用主线程,并且在调用主线程中进行修改。下面有两种方式来实现。
3:可以使用UILabel * lab = [self.view viewWithTag:1]; 来定位到UI控件,比如这里我把UILabel的teg设定成1 。
代码如下:
- (IBAction)GCDAction:(UIButton *)sender {
//块的使用,块中是可以直接访问块外的变量,但是不能直接修改。如果要在块内修改变量,那么该变量是需要这样定义的: __block int num =123;
//1---定义一个无返回值的快
__blockint num =123;
void (^myblock)(void)=^
{
NSLog(@"num = %d", num--);
};
//必须调用块
myblock();
/*2---定义一个有返回值的快
int (^sum)(int)=^(int n)
{
int s = 0;
for (int i = 1; i<= n; i++) {
s+=i;
}
return s;
};
//调用块并且传参
int n = sum(100);
NSLog(@"%d",n);
*/
//启动GCD线程
//获得全局队列,第一个0指的是标示,第二个0指的是一种标志。这是一种固定的写法.后面是一个匿名块
dispatch_async(dispatch_get_global_queue(0,0), ^{
//因为想在非主线程中修改UI控件,那么就需要调用主线程,并且在调用主线程中进行修改,这里也有两种方式来调用主线程
//方式一,把下面的这段代码注入到主线程中。
// dispatch_sync(dispatch_get_main_queue(), ^{
// UILabel * lab = [self.view viewWithTag:1];
// lab.text = @"hello";
// NSLog(@"0000000000");
// });
//方式二,启动主线程中的函数
[selfperformSelectorOnMainThread:@selector(mainn:)withObject:@"222"waitUntilDone:YES];
});
// while (1) {
// NSLog(@"这是主线程");
// }
//
}
-(void)mainn:(id)sender
{
UILabel * lab = [self.viewviewWithTag:1];
lab.text = sender;
}
:
//买火车票事件代码:
- (IBAction)GCDbuyAction:(UIButton *)sender {
__block int tickets = 100;
//线程加锁,避免重复
lock = [[NSLock alloc]init];
void (^sale)()=^{
//设置休眠时间
[NSThread sleepForTimeInterval:5];//该线程睡眠1秒
while (1) {
//加锁
[lock lock];
if (tickets > 0) {
NSLog(@"这个窗口卖出了%d编号这张票", tickets--);
}
[lock unlock];
}
};
//创建五个线程,代表五个售票窗口
dispatch_async(dispatch_get_global_queue(0, 0), sale);
dispatch_async(dispatch_get_global_queue(0, 0), sale);
dispatch_async(dispatch_get_global_queue(0, 0), sale);
dispatch_async(dispatch_get_global_queue(0, 0), sale);
dispatch_async(dispatch_get_global_queue(0, 0), sale);
}