iOS中的多线程(关于NSThread)

915 阅读2分钟

「这是我参与11月更文挑战的第5天,活动详情查看:2021最后一次更文挑战

关于NSThread

NSThread简介

NSThread是苹果官方提供面向对象操作线程的技术,简单方便,可以直接操作线程对象,不过需要自己控制线程的生命周期。在平时使用很少,最常用到的无非就是 [NSThread currentThread]获取当前线程


NSThread使用方法

  • 线程的创建

    • 通过 alloc init 进行创建

      //创建线程
      NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(run:) object:@"text"];
      thread.name = @"my-thread";
      thread.threadPriority = 0.1;
      
      //启动线程
      [thread start];
      
    • 通过 detachNewThreadSelector 方式创建并执行线程

      //创建线程
      [NSThread detachNewThreadSelector:@selector(run:) toTarget:self withObject:@"text"];
      
    • 隐式创建后自动启动线程

      //创建线程
      [self performSelectorInBackground:@selector(run:) withObject:@"text"];
      

    总结:
    第一种方式:设置一些线程属性;例如线程 名字,从控制台信息可以看出来,当设置了不同的 NSThread 对象的优先级属性,可以控制其执行的顺序,优先级越高,越先执行;而设置名字属性后,可以通过调试监控当前所处线程,便于问题分析

    第二、三种方式:创建和操作简单

    示例

    - (void)viewDidLoad {    
        [super viewDidLoad];
        //创建线程 
        [self performSelectorInBackground:@selector(run:) withObject:@"text"];
    }
    
    - (void)run:(NSString *)str{
        for (NSInteger i = 0; i<10; i++) {
            NSLog(@"-run-%ld-%@--%@",(long)i,str,[NSThread currentThread]);
            if(i == 5){
                [self performSelectorOnMainThread:@selector(runMainThread) withObject:nil waitUntilDone:YES];
            }
        }
    }
    
    - (void)runMainThread{
        NSLog(@"回归主线程--%@",[NSThread currentThread]);
    }
    

    log:

    Snip20211103_30.png

  • 线程的状态

    当我们新建一个线程对象的时候,系统就会为其分配一块内存,当你调用线程的开始方法时,就相当于把这个线程放在了线程池里面,等待CPU去调用它,当线程池中有多个线程,那么CPU就会在这几个线程之间来回切换,但是当线程调用了 sleep 或同步锁时,该调用的线程就会被阻塞,当sleep或锁结束时,CPU再次进行切换中,当线程任务执行完,该线程就会释放。


NSThread相关方法

  • 获取当前线程

    @property (class, readonly, strong) NSThread *currentThread;
    
  • 获得主线程

    + (NSThread *)mainThread;
    
  • 判断当前线程是否为主线程

    - (BOOL)isMainThread;
    + (BOOL)isMainThread;
    
  • 进入就绪状态 -> 运行状态。当线程任务执行完毕,自动进入死亡状态

    - (void)start;
    
  • 进入阻塞状态

    + (void)sleepUntilDate:(NSDate *)date;
    + (void)sleepForTimeInterval:(NSTimeInterval)time;
    
  • 强制停止线程,一旦线程停止(死亡)了,就不能再次开启任务

    + (void)exit;
    

示例

- (void)viewDidLoad {
    [super viewDidLoad];
    
    //创建线程
    [NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];
}

- (void)run{

    NSLog(@"线程睡眠");
    [NSThread sleepForTimeInterval:2];
    NSLog(@"线程唤醒");
    
    for (NSInteger a = 0; a<10; a++) {
        NSLog(@"-执行");
        if (a == 5){
            NSLog(@"退出线程");
            [NSThread exit];//退出线程
            NSLog(@"不会打印");
        }
    }
}

log:

Snip20211103_27.png