zoukankan      html  css  js  c++  java
  • iOS多线程实现2-NSThread

      NSThread是轻量级的多线程开发,OC语言编写,更加面向对象,使用起来也并不复杂,但是使用NSThread需要自己管理线程生命周期,如果长期运行还要考虑内存释放的问题,比如自动释放池的创建于销毁。在iOS开发中很少使用它来创建一个线程,但是经常使用它做一些延时操作,获取当前线程,线程间通讯等等。

      但是,在线程同步方面,控制线程执行顺序比较麻烦,线程同步对数据的加锁会有一定的系统开销,且创建线程也会增加系统的开销。

      1 创建方法

      有多种创建方法,- (void)runDemo:(NSString *)param;为要执行的示例方法。

    - (void)runDemo:(NSString *)param {
        NSThread *current = [NSThread currentThread];
        NSLog(@"%@---%@ is running", param, current);
    }
    /// 方式1 自动创建线程, 并且自动启动
    - (void)threadCreateOne {
        // 在另一个线程执行 runDemo:
        [self performSelectorInBackground:@selector(runDemo:) withObject:@"One"];
    }
    
    /// 方式2 创建完线程直接(自动)启动
    - (void)threadCreateTwo {
        [NSThread detachNewThreadSelector:@selector(runDemo:) toTarget:self withObject:@"Two"];
    }
    
    /// 方式3  先创建初始化线程,然后start开启线程
    - (void)threadCreateThree {
        NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(runDemo:) object:@"Three"];
        // 可以设置线程名字
        thread.name = @"名字";
        // 开启线程
        [thread start];
    }

       下面为测试代码,以及打印结果,我们调用的顺序是One->Two->Three,但是打印结果是Two->Three->One,因为线程启动后仅仅处于就绪状态,实际是否执行要由CPU根据当前状态调度,即执行顺序是无序的,这也是多线程的特点。

    /// 点击屏幕后创建线程
    - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event{
        [self threadCreateOne];
        [self threadCreateTwo];
        [self threadCreateThree];
    }
    
    打印结果:
    2015-08-27 16:27:34.974 01test[1183:76667] Two---<NSThread: 0x7ff250e1c9a0>{number = 3, name = (null)} is running
    2015-08-27 16:27:34.974 01test[1183:76668] Three---<NSThread: 0x7ff250e168a0>{number = 4, name = 名字} is running
    2015-08-27 16:27:34.974 01test[1183:76666] One---<NSThread: 0x7ff250f406a0>{number = 2, name = (null)} is running

      2 常用函数

      获取当前线程,获取主线程,判断当前线程是否为主线程。

    // 获取当前线程
    NSThread *current = [NSThread currentThread];
    // 获取主线程
    current = [NSThread mainThread];
    // 判断当前线程是否为主线程
    BOOL isMain = [current isMainThread];

       暂停线程,下面代码为2种方法均让当前线程睡5s

    [NSThread sleepForTimeInterval:5];
    NSDate *date = [NSDate dateWithTimeInterval:5 sinceDate:[NSDate date]];
    [NSThread sleepUntilDate:date];

      获取线程的状态,分别为:正在执行、已经完成、已经取消。

    @property (readonly, getter=isExecuting) BOOL executing;
    @property (readonly, getter=isFinished)  BOOL finished;
    @property (readonly, getter=isCancelled) BOOL cancelled;

      在指定的线程(已存在的线程)、主线程、当前线程上执行方法。这种比较常用,通常用于线程间通讯,且它们是NSObject的扩展方法,使用起来很方便。

    // 在指定的线程执行runDemo:方法,最后的YES代表:下面的代码会阻塞,等runDemo:方法在thread线程执行完毕后,才会执行下面代码的下一行代码,设为NO则不阻塞。那么runDemo:与下一行代码的执行顺序不确定
    [self performSelector:@selector(runDemo:) onThread:thread withObject:nil waitUntilDone:YES];
    // 在主线程执行runDemo:方法,YES参数同上
    [self performSelectorOnMainThread:@selector(runDemo:) withObject:nil waitUntilDone:YES];
    // 在当前线程执行方法
    [self performSelector:@selector(run) withObject:nil];

      退出线程:杀死线程,会阻碍线程内部自身的清理工作,所以最好让线程自己正常退出,而不是类似exit()这样的强制退出,(虽然很方便)

    + (void)exit;

      线程优先级相关,优先级范围是0.0 ~ 1.0,默认0.5,值越大,优先级越高。开发时,很少使用优先级,如果设置优先级且使用线程锁会造成优先级翻转,需要特备注意。

    + (double)threadPriority;
    + (BOOL)setThreadPriority:(double)p;
  • 相关阅读:
    linux下netstat命令详解
    linux下strace命令详解
    /proc/uptime
    趣味理解网关、路由等概念
    OPENCV运行的问题,自带的程序可以运行,但是自己制作的QT报错
    第九章 MIZ702 ZYNQ片上ADC的使用
    第四章 MIZ701 ZYNQ制作UBOOT固化程序
    第三章 VIVADO 自定义IP 流水灯实验
    第一章 MIZ701 VIVADO 搭建SOC最小系统HelloWorld
    Zynq-7000 MiZ701 SOC硬件使用手册
  • 原文地址:https://www.cnblogs.com/mddblog/p/4763925.html
Copyright © 2011-2022 走看看