一、多线程
1、什么是多线程
NSThread
(1)多线程可以同时处理多个任务的请求。如果要同时执行多个任务,需要开启一个新的线程。程序执行的时候串行执行,如果多个任务执行是并行执行。
//创建新的线程1 NSThread *thread1 =[[NSThread alloc]initWithTarget:self selector:@selector(taska:) object:nil]; [thread1 start]; //创建新线程2 [NSThread detachNewThreadSelector:@selector(taskb:) toTarget:self withObject:nil];
(2)多线程能解决什么问题?
//
本质上,主要是解决某个耗时的任务执行时出现的界面卡死的问题,保证多个任务可以同时执行,比如迅雷下载。
//
场景使用,如大麦网,有的图片下载耗时5秒,或者加载1G的文件,需要启动多线程。
//
(3) 线程的同步以及锁 演示问题
CPU从内存中拿出数据更改值然后放回内存,如果多线程访问,结果可能不正确。解决方式是加锁。
-(void)add { for (int i=0; i<1000; i++) { [_lock lock]; _num ++; NSLog(@"add ==%d",_num); [_lock unlock]; } } -(void)sub { for (int i=0; i<1000; i++) { [_lock lock]; _num --; NSLog(@"sub ==%d",_num); [_lock unlock]; } }
项目开发中,noatomic当一个属性只有UI界面访问可以加,提高访问速度。如果这个属性会被创建的子线程访问时不要加noatomic保证线程的安全。
UI线程称为主线程,其他创建的线程称为工作子线程
注意:不要在子线程中直接操作UI
{ .......
///子线程如何更新UI(重要),避免代码出问题。eg:下载进度更新 ///UI线程称为主线程,其他创建的线程称为工作子线程,注意:不要在子线程中直接操作UI(间接让主线程操作UI) _progressView =[[UIProgressView alloc] initWithFrame:CGRectMake(50, 200, 250, 10)]; [self.view addSubview:_progressView]; [NSThread detachNewThreadSelector:@selector(downloadNetworkingData) toTarget:self withObject:nil]; } #pragma mark --演示下载数据 -(void)downloadNetworkingData { //模拟10s网络下载 for (int i=0; i<100; i++) { //_progressView.progress +=0.01;不要在这里操作UI界面 // 以下语句是间接操作UI的过程 [self performSelectorOnMainThread:@selector(updateUI) withObject:nil waitUntilDone:YES]; [NSThread sleepForTimeInterval:0.1]; } } -(void)updateUI {_progressView.progress +=0.01;}
二、NSOpetation
1、什么是NSOperation
也是实现多线程的一种机制,在NSThread做了更高的抽象,加入了Block,比NSThread简单易用
三 、GCD
1、Grand Central Dispatch 简写
优点:支持多核心,C和BLOCK接口,易于使用,功能强大。
1.创建一个异步任务
[ self creatAsyncTask];
2.模拟网络下载
[self simulateNewokingDownload];
3.只是执行一次
[self runOnce];
4。延时执行
[self delayRun];
5 通知执行多个任务,等待所有任务执行完成时进行处理
[self groupRun];
===============
-(void)groupRun
{ //group 任务组
dispatch_group_t group =dispatch_group_create();
//添加任务,7秒完成
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//
for (int i=0; i<100; i++) {
NSLog(@"A=%d",i);
[NSThread sleepForTimeInterval:0.07];
}
});
//添加任务,5秒完成
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//
for (int i=0; i<100; i++) {
NSLog(@"B=%d",i);
[NSThread sleepForTimeInterval:0.05];
}
});
//添加任务,10秒完成
dispatch_group_async(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
//
for (int i=0; i<100; i++) {
NSLog(@"C=%d",i);
[NSThread sleepForTimeInterval:0.1];
}
});
// 监控完成后的操作
dispatch_group_notify(group, dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
NSLog(@"全部任务完成了");
});
}
-(void)delayRun
{
//5s后输出
dispatch_after(dispatch_time(DISPATCH_TIME_NOW,(int64_t)(5*NSEC_PER_SEC) ), dispatch_get_main_queue(), ^{
//
NSLog(@"haha");
});
}
-(void)runOnce
{
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
NSLog(@"只执行一次的代码");
});
}
-(void)simulateNewokingDownload
{
_progressView =[[UIProgressView alloc] initWithFrame:CGRectMake(50, 200, 250, 10)];
[self.view addSubview:_progressView];
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
for (int i=0; i<10; i++) {
//
//最后显示对话框
dispatch_async(dispatch_get_main_queue(), ^{
_progressView.progress +=0.1;
});
[NSThread sleepForTimeInterval:1];
}
dispatch_async(dispatch_get_main_queue(), ^{
UIAlertView *alertView =[[UIAlertView alloc] init];
alertView.message =@"下载完成";
[alertView addButtonWithTitle:@"取消"];
[alertView show];
});
});
}
#pragma mark --GCD测试方法
-(void)creatAsyncTask
{
//创建一个异步任务,参数1,传入queue,有3种queue: main queue 主队列 ;global queue 全局队列,工作线程;自定义queue
dispatch_queue_t queue=dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
dispatch_async(queue, ^{
for (int i=0; i<20; i++) {
NSLog(@"A===%d",i);
}
});
dispatch_async(queue, ^{
for (int i=0; i<20; i++) {
NSLog(@"B===%d",i);
}
});
}