#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//多线程 -- 为了将一些耗时的操作放在多线程中,主要是为了有一个良好的用户体验,防止出现卡顿的效果
//注:不是线程开的越多越好,线程多了会消耗CPU的使用效率
//创建多线程的方式:
//1.NSThread
//2.CGD
//3.NSOparation
//程序运行的时候,默认会给我创建一个线程,这个线程我们通常叫主线程/UI线程,所有与UI相关的操作都需要在这个线程中执行
for (int i = 0; i < 50; i++) {
NSLog(@"主线程==%@==%d",[NSThread currentThread],i);
//isMainThread 判断是否是主线程
BOOL ret = [NSThread isMainThread];
if (i == 5) {
// [self threadRun];
// [self createThread1];
// [self createThread2];
[self createThread3];
}
}
}
- (void)createThread1{
//1.创建线程 减方法创建
//操作 --- 功能 --- 若干行代码 -- 函数 -- 任务
NSThread *thread1 = [[NSThread alloc]initWithTarget:self selector:@selector(threadRun) object:nil];
//第三个参数:object 如果第二个参数selector带参的话,object就是该方法的参数
//新创建的线程可以称之为子线程/任务线程/后台线程
//设置线程的名字
thread1.name = @"子线程1";
//设置线程的优先级 0 -- 1之间
thread1.threadPriority = 0.5;
//设置线程的优先级
thread1.qualityOfService = NSQualityOfServiceDefault;
//qualityOfService 要在start之前设置 否则无效
//2.开启线程
[thread1 start];
}
- (void)threadRun{
//当前线程
NSThread *thread = [NSThread currentThread];
//isMultiThreaded 判断是否是多线程
BOOL ret = [NSThread isMultiThreaded];
for (int i = 0; i < 50; i++) {
// sleep(2);
NSLog(@"子线程-%@-%d",[NSThread currentThread],i);
//[NSThread currentThread] 当前线程
}
}
- (void)createThread2{
//创建线程 加方法创建
[NSThread detachNewThreadSelector:@selector(threadRun) toTarget:self withObject:nil];
//创建线程即执行线程
//用这个方法设置不了线程的名字
}
- (void)createThread3{
//NSObject方法 创建线程
[self performSelectorInBackground:@selector(threadRun) withObject:nil];
}
@end
多线程-NSThreed.png
NSThread案列
#import "ViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//创建线程
NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(downLoadImage) object:nil];
//启动线程
[thread start];
}
- (void)downLoadImage{
NSLog(@"子线程--%@",[NSThread currentThread]);
//将耗时的操作放到子线程中执行
NSString *str = @"http://onepiece.local/SH/1.jpg";
NSURL *url = [NSURL URLWithString:str];
NSData *data = [NSData dataWithContentsOfURL:url];
//显示数据需要让主线程操作/UI的操作让主线程来做
//让主线去做事情 和主线程通讯
// [self performSelectorOnMainThread:@selector(showImage:) withObject:data waitUntilDone:YES];
//第三个参数:是否等该线程的方法执行结束 再继续执行
//和任意线程通讯
[self performSelector:@selector(showImage:) onThread:[NSThread mainThread] withObject:data waitUntilDone:YES];
//[NSThread mainThread] 拿到主线程
//[NSThread currentThread] 拿到当前线程
NSLog(@"继续执行");
}
- (void)showImage:(NSData *)data{
//线程休眠几秒
[NSThread sleepForTimeInterval:2.f];
//线程休眠几秒
// [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:2.f]];
// sleep(2);
NSLog(@"主线程==%@",[NSThread currentThread]);
//主线程显示数据
self.imageView.image = [UIImage imageWithData:data];
}
@end
NSThread线程之间的通讯
#import "ViewController.h"
@interface ViewController ()
@property (weak, nonatomic) IBOutlet UIImageView *imageView;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//创建线程
NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(downLoadImage) object:nil];
//启动线程
[thread start];
}
- (void)downLoadImage{
NSLog(@"子线程--%@",[NSThread currentThread]);
//将耗时的操作放到子线程中执行
NSString *str = @"http://onepiece.local/SH/1.jpg";
NSURL *url = [NSURL URLWithString:str];
NSData *data = [NSData dataWithContentsOfURL:url];
//显示数据需要让主线程操作/UI的操作让主线程来做
//让主线去做事情 和主线程通讯
// [self performSelectorOnMainThread:@selector(showImage:) withObject:data waitUntilDone:YES];
//第三个参数:是否等该线程的方法执行结束 再继续执行
//和任意线程通讯
[self performSelector:@selector(showImage:) onThread:[NSThread mainThread] withObject:data waitUntilDone:YES];
//[NSThread mainThread] 拿到主线程
//[NSThread currentThread] 拿到当前线程
NSLog(@"继续执行");
}
- (void)showImage:(NSData *)data{
//线程休眠几秒
[NSThread sleepForTimeInterval:2.f];
//线程休眠几秒
// [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:2.f]];
// sleep(2);
NSLog(@"主线程==%@",[NSThread currentThread]);
//主线程显示数据
self.imageView.image = [UIImage imageWithData:data];
}
@end
NSThread线程的优先级
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
NSThread *thread1 = [[NSThread alloc]initWithTarget:self selector:@selector(threadRun) object:nil];
NSThread *thread2 = [[NSThread alloc]initWithTarget:self selector:@selector(threadRun) object:nil];
thread1.name = @"线程1";
thread2.name = @"线程2";
//threadPriority线程优先级
NSLog(@"主线程==%g",[NSThread mainThread].threadPriority);//默认优先级0.75/0.5
NSLog(@"子线程1--%g",thread1.threadPriority);//默认优先级0.5
NSLog(@"子线程2--%g",thread2.threadPriority);//默认优先级0.5
//优先级高的线程的线程 先执行
thread1.threadPriority = 1;
thread2.threadPriority = 0;
[thread1 start];
[thread2 start];
}
- (void)threadRun{
for (int i=0; i<50; i++) {
NSLog(@"当前线程:%@ --%d",[NSThread currentThread].name,i);
}
}
@end
NSThread线程的优先级.png
NSThread线程的退出
#import "ViewController.h"
@interface ViewController ()
@end
@implementation ViewController
{
NSThread *thread;
}
- (void)viewDidLoad {
[super viewDidLoad];
thread = [[NSThread alloc]initWithTarget:self selector:@selector(threadRun) object:nil];
thread.name = @"子线程";
//启动线程
[thread start];
//监听线程的退出
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(threadOut) name:NSThreadWillExitNotification object:nil];
//NSThreadWillExitNotification 线程退出的频道
//只需要监听这个频道 当线程退出时 就会收到通知/消息 然后调用相应的方法
/*
FOUNDATION_EXPORT NSString * const NSWillBecomeMultiThreadedNotification;
FOUNDATION_EXPORT NSString * const NSDidBecomeSingleThreadedNotification;
FOUNDATION_EXPORT NSString * const NSThreadWillExitNotification;
*/
}
- (void)threadOut{
NSLog(@"线程退出了");
}
- (void)threadRun{
for (int i = 0; i < 50; i++) {
if (thread.isCancelled) {
//如果isCancelled为YES
//退出线程 exit 也可以使用return
[NSThread exit];
}
[NSThread sleepForTimeInterval:1.f];
NSLog(@"%@-%d",[NSThread currentThread].name,i);
}
//threadRun这个方法是我们子线程的入口函数(main函数)--当这个方法执行完的时候,线程就已经是死亡状态
}
- (IBAction)clickThreadOut:(UIButton *)sender {
//取消线程 cancel并不能把一个线程退出 调用cancel只是为了告诉当前线程的isCancelled属性为YES
[thread cancel];
// thread.isCancelled
}
@end
NSThread线程的退出.png
线程锁-生产者与消费者
#import "ViewController.h"
@interface ViewController ()
@property (nonatomic,strong) NSLock *lock;
@end
@implementation ViewController
- (void)viewDidLoad {
[super viewDidLoad];
//创建了一个线程锁
self.lock = [[NSLock alloc]init];
NSThread *thread1 = [[NSThread alloc]initWithTarget:self selector:@selector(eat) object:nil];
thread1.name = @"夏洛";
[thread1 start];
NSThread *thread2 = [[NSThread alloc]initWithTarget:self selector:@selector(eat) object:nil];
thread2.name = @"马冬梅";
[thread2 start];
NSThread *thread3 = [[NSThread alloc]initWithTarget:self selector:@selector(eat) object:nil];
thread3.name = @"秋雅";
[thread3 start];
}
- (void)eat{
static int num = 50;
while (1) {
//加锁之后 同一时刻只允许一个线程访问
//加锁 数据修改之前
[self.lock lock];
num --;
NSLog(@"%@吃了一碗茴香打卤面 还剩……%d碗",[NSThread currentThread].name,num);
[NSThread sleepForTimeInterval:2.f];
if (num == 0) {
break;
}
//解锁 数据修改完成
[self.lock unlock];
}
}
@end
网友评论