一个NSThread对象就代表一条线程。
1.创建、启动线程
1)方式一
NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(run) object:nil];
[thread start];
/*线程一启动,就会在线程thread中执行self的run方法*/
2)方式二
/*这种方式线程会自动启动*/
[NSThreaddetachNewThreadSelector:@selector(run) toTarget:selfwithObject:@"hello"];
3)方式三
/*"隐式"方式,线程会自动启动*/
[selfperformSelectorInBackground:@selector(run) withObject:@"hello"];
2.主线程相关用法
/*获得主线程*/
+(NSThread *)mainThread;
/*是否为主线程*/
-(BOOL)isMainThread;
3.线程的属性
/*创建线程*/
NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(run) object:@"hello"];
/*线程名*/
thread.name = @"thread A";
/*线程优先级,一般不设置(值是一个小数0.0-1.0,默认是0.5),只有多个线程才生效*/
thread.threadPriority = 0.1;
/*开启线程*/
[threadstart];
4.线程状态
5.线程操作
//启动线程
-(void)start;
//进入就绪状态à运行状态。当线程任务执行完毕,自动进入死亡状态。
//阻塞(暂停)线程
+(void)sleepUntilDate:(NSDate *)date;
+(void)sleepForTimeInterval:(NSTimeInterval)ti;
//进入阻塞状态
//强制停止线程
+(void)exit;
//进入死亡状态
注意:一旦线程停止(死亡),就不能再次开启任务。
6.多线程的安全隐患
1)资源共享
一块资源可能会被多个线程共享,也就是多个线程可能会访问同一块资源。
比如,多个线程访问同一个对象、同一个变量、同一个文件。
2)当多个线程访问同一块资源时,很容易引发数据错乱和数据安全问题。
7.互斥锁
/*参数:任何继承(NSObject*)对象都可以。一般使用self*/
/*苹果官方不推荐使用加锁,加锁后性能太差*/
@synchronized(self){ //需要加锁的代码 }
加锁范围尽量小。
加锁范围内的代码,同一时间只允许一个线程执行。
要保证所有线程都能访问到锁内代码,而且所有线程访问的是同一个锁对象。
8.原子属性
nonatomic:非原子属性。
atomic:原子属性,默认属性。针对多线程设计的,保证单(线程)写多(线程)读。即只对写操作(setter方法)进行加锁。内部使用自旋锁,没有互斥锁的唤醒过程。
atomic情况下,只要重写了setter方法,getter方法也需要重写。
9.线程安全的概念
在多个线程同时执行的时候,能够保证资源信息的准确性。
10.UI线程——主线程
UIKit中绝大部分的类,都不是“线程安全”的。
在主线程更新UI的优点有哪些?
1)只在主线程更新UI,就不会出现多个线程同时改变同一个UI控件。
2)主线程的优先级最高,也就意味着UI的更新优先级高,会让用户感觉很流畅。
11.线程间通信
-(void)downloadImage:(UIImage *)image
{
self.iconView.image= image;
}
/* waitUntilDone:表示是否等待@selector(downloadImage:)方法完成。*/
[selfperformSelectorOnMainThread:@selector(downloadImage:) withObject:imagewaitUntilDone:NO];
12.运行循环
在iOS开发中几乎不用。
作用:
1)保证程序不退出。
2)监听所有事件,例如:手势触摸,时钟触发,网络加载数据完成等。
特性:
1)没有事件时,会休眠(省电),一旦监听到事件,会立即响应。
2)每一个线程都有一个runloop,但是只有主线程的runloop会默认启动。
13.按钮点击事件
14.自动释放池
自动释放池什么时候创建?什么时候销毁?