一.NSThread 线程创建方式
selector后为线程调用的方法,object后为传入线程方法的参数类
NSThread *thread=[[NSThread alloc]initWithTarget:self selector:@selector(run:) object:@“abc”];
需要调[thread start];
//从主线程中分离一个子线程去执行任务,无需手动开启,分离出来后会立即启动
[NSThread detachNewThreadSelector:@selector(run:) toTarget:self withObject:@“miss”];
//开一个后台线程,无需手动启动
[self performSelectorInBackground:@selector(run:) withObject:@“back”];
//把耗时操作放在子线程的方法中执行,防止界面卡顿
-(void)run:(id)obj{}
获取当前线程[NSThread currentThread];
获取主线程[NSThread mainThread];
二.线程状态
1.新建线程,alloc,开辟一段内存空间放置线程对象
2.开启线程,start,线程对象会被放置到对应的线程池中。就绪状态,等待CPU调度。
3.当CPU调度该线程时,运行状态。
4.当CPU调度其他线程的时候,返回就绪状态。
5.当调用了sleep/等待同步锁,进入阻塞状态(blocked),线程对象从线程池中移出来;当sleep到时/等到了同步锁,线程进入就绪状态,线程对象回归到线程池中,等待CPU调度。
6.线程的死亡,线程任务执行完成,自动死亡;线程异常/强制退出。
一旦线程死亡,线程对象从内存中移除,不能再重新开启,如果尝试重新开启线程,程序会挂掉。
线程休眠
第一种方法
[NSThread sleepForTimeInterval:2];
第二种方法
[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:2]];
如果想线程任务执行一部分之后永远不要开启
[NSThread sleepUntilDate:[NSDate distantFuture]];//在遥远的未来
线程强制退出
[NSThread exit] ;
三.线程安全隐患
一块资源可能会被多个线程共享,即多个线程同时访问操作同一个数据(对象,变量,文件)(线程并发执行),很容易引发数据错乱和数据安全问题。
解决方案:使用线程同步技术(按先后顺序执行),常用技术是加锁。
@synchronized
互斥锁的优点:有效防止因多线程抢夺资源造成的数据安全问题。
缺点:因为线程等待,需要消耗大量的CPU资源。
注意:互斥锁又叫线程同步。
线程同步:多条线程在同一条线上执行,按顺序执行任务。
@synchronized(self) 创建一个互斥锁,保证此时没有其他线程对self对象进行修改
@synchronized(锁对象){//需要锁定的代码}
锁对象是同一个,是唯一的。
四.线程通信
在一个进程中,线程往往不是孤立存在的,多个线程之间是存在有通信关系的。
体现:
1.一个线程传递数据给另一个线程
2.一个线程执行完成任务后转到另外一个线程继续执行任务。
eg:在子线程中做耗时操作加载网络图片,然后回到主线程显示网络图片。
self.imageView.image=[UIImage imageNamed: name];添加的图片是在工程内部的图片。
从网络下载的图片用self.imageView.image=[UIImage imageWithData: data];
NSURL *url=[NSURL URLWithString:IMAGE_URL];
NSData *data=[NSData dataWithContentsOfURL:url];
UIImage *image=[UIImage imageWithData:data];
注意:xcode7以后如果想要使用http协议,需要在Info.plist里面添加字段. App Transport Security settings / Allow Arbitrary Loads YES
//查看代码的执行时间
NSDate *begin=[NSDate date];
代码
NSDate *end=[NSDate date];
NSLog(@"%f",[end timeIntervalSinceDate:begin]);
由子线程回归到主线程:
在子线程的方法里调:
[self performSelectorOnMainThread:@selector(loadImage:) withObject:image waitUntilDone:YES];
或
[self performSelector:@selector(loadImage:) onThread:[NSThread mainThread] withObject:image waitUntilDone:YES];
或
[self.imageView performSelector:@selector(setImage:)onThread:[NSThread mainThread] withObject:image waitUntilDone:YES];
说明:waitUntilDone:YES,等@selector里的方法执行完后,才执行之后的代码,
waitUntilDone:NO, @selector里的方法和之后的代码是并发执行的。