美文网首页
7.2 多线程-NSThreed

7.2 多线程-NSThreed

作者: 草根小强 | 来源:发表于2019-04-22 12:00 被阅读0次
#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

相关文章

网友评论

      本文标题:7.2 多线程-NSThreed

      本文链接:https://www.haomeiwen.com/subject/mzhygqtx.html