线程
程序: 安装在移动设备上的一个应用, 都是一个程序的
进程: 正在运行的每一个应用程序就是一个进程, 进程相当于一个任务,
线程: 执行任务单元片段叫做线程, 也就是任务的真正执行者, 只不过系统默认把任务交给一个线程来做, 这个线程就是主线程, 为了提高用户体验,我们需要把耗时的操作交给子线程
线程同步: 任务与任务直接按存在先后关系, 后一个任务的执行, 必须等待前一个任务结束
线程并发: 任务与任务之间没有关系, 先执行的线程, 有可能是最后一个完成的任务
主线程跳转到子线程执行任务: 直接创建子线程, 执行对应的耗时的任务即可
子线程跳转到主线程执行任务: 对于界面的刷新操作, 交由主线程操作, 使用performSelectorOnMainThread::: 操作
//对于耗时的操作交由子线程来完成, 主线程依旧可以处理用户交互和界面的变化
// 1.创建子线程, 使用线程类: NSthread
[NSThread detachNewThreadSelector:@selector(taskone) toTarget:self withObject:nil];
(taskone)当前任务在主线程完成, 未完成之前不会执行后面的代码
// 2.创建子线程, 使用线程类: 需要手动开启
NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(taskOne)
[thread start];
[thread release];
// 3.创建子线程, 使用NSObject 提供的方法
[self performSelectorInBackground:@selector(downloadImage) withObject:nil];
//主线程中开启定时器
//创建子线程, 开启定时器
// [self performSelectorInBackground:@selector(startTime) withObject:nil];
- (void)startTime {
//子线程没有自动释放池, 遍历构造器内部操作是 autorelease 来操作, 因此, 需要自己添加自动释放池
@autoreleasepool {
[NSTimer scheduledTimerWithTimeInterval:0.5 target:self selector:@selector(taskThree) userInfo:nil repeats:YES];
//在子线程中刚开启事件循环, 正是有了时间循环, 定时器才能够重复执行任务
[[NSRunLoop currentRunLoop]run];
}
}
// 4.创建子线程 使用任务队列 任务队列会为队列中的任务合理安排子线程来完成任务
NSInvocationOperation *op1 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(taskFour) object:nil];
NSInvocationOperation *op2 = [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(taskFive) object:nil];
//创建任务队列, 将任务添加到任务队列中
NSOperationQueue *quene = [[NSOperationQueue alloc]init];
//1.实现线程同步第一种: 设置最大并发数
[quene setMaxConcurrentOperationCount:1];
//2.实现线程同步第二种; 添加依赖关系
[op2 addDependency:op1];
[quene addOperation:op1];
//blcok 也能实现线程同步
/*
NSBlockOperation *op1 = [NSBlockOperation blockOperationWithBlock:^{
for (int i = 0; i < 5; i++) {
NSLog(@"蓝鸥");
}
}];
NSBlockOperation *op2 = [NSBlockOperation blockOperationWithBlock:^{
for (int i = 0;i < 5 ; i++) {
NSLog(@"北京");
}
}];
//线程互斥: 当多个线程访问同一个资源时, 一个线程访问, 其他线程等待, 此时需要加锁.
@property (nonatomic, retain)NSLock *lock;
[self.lock lock];
...
[self.lock unlock];
线程死锁: 裂解资源减少解锁的过程, 就容易造成死锁, 一个线程等待另一个线程释放资源, 但是, 前一个资源缺少解锁过程, 造成后一个线程一直处于等待状态
//验证当前线程是否是主线程
NSLog(@"当前线程: %@, 是否是主线程:%d",[NSThread currentThread], [[NSThread currentThread] isMainThread]);