zoukankan      html  css  js  c++  java
  • 【iOS】从实际出发理解多线程(二)--NSThread基础操作

    简介

    NSthread是苹果官方提供面向对象操作线程的技术,简单方便,可以直接操作线程对象,不过需要自己控制线程的生命周期。在平时使用较少,常用的就是下面的方法来获取当前线程。

    [NSThread currentThread]

    使用

    1.实例初始化、属性和实例方法

    初始化

    切记下面两个方法初始化的NSThread必须手动start开启线程
    //创建线程
    NSThread *newThread = [[NSThread alloc]initWithTarget:self selector:@selector(demo:) object:@"Thread"];
    //或者
    NSThread  *newThread=[[NSThread alloc]init];
    NSThread  *newThread= [[NSThread alloc]initWithBlock:^{
      NSLog(@"initWithBlock");
    }];

    属性

    线程字典

    /**
    每个线程都维护了一个键-值的字典,它可以在线程里面的任何地方被访问。
    你可以使用该字典来保存一些信息,这些信息在整个线程的执行过程中保持不变。
    比如,你可以使用它来存储在你的整个线程过程中 Run loop 里面多次迭代的状态信息。
    NSThread实例可以使用以下方法
    */
    
    @property (readonly, retain) NSMutableDictionary *threadDictionary;
    NSMutableDictionary *dict = [thread threadDictionary];  

    优先级

    @property double threadPriority ; //优先级

    线程优先级

    /** NSQualityOfService:
      NSQualityOfServiceUserInteractive:最高优先级,主要用于提供交互UI的操作,比如处理点击事件,绘制图像到屏幕上
      NSQualityOfServiceUserInitiated:次高优先级,主要用于执行需要立即返回的任务
      NSQualityOfServiceDefault:默认优先级,当没有设置优先级的时候,线程默认优先级
      NSQualityOfServiceUtility:普通优先级,主要用于不需要立即返回的任务
      NSQualityOfServiceBackground:后台优先级,用于完全不紧急的任务
    */
    @property NSQualityOfService qualityOfService

    线程名称

    @property (nullable, copy) NSString *name;

    线程使用栈区大小,默认是512k

    @property NSUInteger stackSize ;

    线程状态(正在执行、执行结束、是否可以取消)

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

    实例方法

    // 启动线程  实例化线程需要手动启动才能运行
    - (void)start;
    [thread stary]
    
    
    // 是否为主线程
    - (BOOL)isMainThread; 
    isMain = [thread isMainThread];
    
    //设置线程名称
    - (void)setName:(NSString *) name;
    [thraed setName:@"name"];
    
    // 取消线程 
    - (void)cancel;
    [thread  cancel];
    
    // 线程的入口函数
    - (void)main; 
    [thread main];
    
    // 线程是否正在执行
    - (void)isExecuting;
    isRunning=[thread isExecuting];
    
    // 线程是否已经结束
    - (void)isFinished;
    isEnd=[thread isFinished];
    
    // 线程是否撤销
    - (void)isCancelled;
    isCancel=[thread isCancelled];

    类创建方法

    /*
       创建子线程并开始
       创建后就可执行,不需要手动开启
    但是不能获取NSThread对象
    */ /** block方式 具体的任务在Block中执行 */ + (void)detachNewThreadWithBlock:(void (^)(void))block; /** SEL方式 利用selector方法初始化NSThread,target指selector方法从属于的对象 selector方法也 是指定的target对象的方法 */ + (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(nullable id)argument;

    类使用方法

    // 获取当前线程
    + (void)currentThread;
    [NSThread currentThread];
    
    //当前代码运行所在线程是否为子线程
    + (BOOL)isMultiThreaded;
    isMulti = [NSThread isMultiThreaded];
    
    // 当前代码所在线程睡到指定时间  
    + (void)sleepUntilDate: (NSDate *)date; 
    [NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.0]];
    
    // 线程沉睡时间间隔,这个方法在设置启动页间隔的时候比较常见
    + (void)sleepForTimeInterval: (NSTimeInterval)time;
    [NSThread sleepForTimeInterval:1.0];
    
    // 退出当前线程
    + (void)exit;
    [NSThread exit];
    
    // 设置当前线程优先级
    + (double)threadPriority;
    double dPriority=[NSThread threadPriority];
    
    // 给当前线程设定优先级,调度优先级的取值范围是0.0 ~ 1.0,默认0.5,值越大,优先级越高。
    + (BOOL)setThreadPriority:(double)priority;
    BOOL isSetting=[NSThread setThreadPriority:(0.0~1.0)];
    
    // 线程的调用都会有行数的调用函数的调用,就会有栈返回地址的记录,
    在这里返回的是函数调用返回的虚拟地址
    说白了就是在在该先出中函数调用的虚拟地址的数组
    + (NSArray *)callStackReturnAddresses;
    NSArray *addressArray=[NSThread callStackReturnAddresses];
    
    // 同上面的方法一样,只不过返回的是该线程调用函数的名字数字
    + (NSArray *)callStackSymbols;
    NSArray* nameNumArray=[NSThread callStackSymbols];
    
    注意:callStackReturnAddress和callStackSymbols这两个函数可以同NSLog联合使用来跟踪线程的函数调用情况,是编程调试的重要手段

     隐式创建&线程间通讯

    以下方法位于NSObject(NSThreadPerformAdditions)分类中,所有继承自NSObject实例化对象都可以调用以下方法。

    /**
      指定方法在主线程中执行
      参数1. SEL 方法
        2.方法参数
        3.BOOL类型  表示是否等待当前aSelector方法执行完毕
        4.指定的Runloop model
    */
    - (void)performSelectorOnMainThread:(SEL)aSelector withObject:(nullable id)arg waitUntilDone:(BOOL)wait modes:(nullable NSArray<NSString *> *)array;
    - (void)performSelectorOnMainThread:(SEL)aSelector withObject:(nullable id)arg waitUntilDone:(BOOL)wait;
        // equivalent to the first method with kCFRunLoopCommonModes
    /**
      指定方法在某个线程中执行
      参数1. SEL 方法
        2.方法参数
        3.是否等待当前执行完毕
        4.指定的Runloop model
    */
    - (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(nullable id)arg waitUntilDone:(BOOL)wait modes:(nullable NSArray<NSString *> *)array API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
    - (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(nullable id)arg waitUntilDone:(BOOL)wait API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
        // equivalent to the first method with kCFRunLoopCommonModes
    /**
      指定方法在开启的子线程中执行
      参数1. SEL 方法
        2.方法参数
    */
    - (void)performSelectorInBackground:(SEL)aSelector withObject:(nullable id)arg API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
    

    注意:我们提到的线程间通讯就是这几个方法,没有多高大上多复杂。

    再注意:苹果声明UI更新一定要在UI线程(主线程)中执行,虽然不是所有后台线程更新UI都会出错。

    再注意:waitUntilDone后面的这个BOOL类型的参数,这个参数的意义有点像我们是否同步执行aSelector这个任务!具体的看下面两张图的内容就一目了然了。

     

  • 相关阅读:
    线性表的各种基本操作
    malloc&&free的系统运行机制及其源代码的理解
    剪枝的定义&&hdu1010
    hdu 1045
    hdu2094 stl之set的应用
    关联式容器的总结
    STL之map容器的详解
    2018-2019 ACM-ICPC 焦作赛区 部分题解
    2018-2019 ACM-ICPC 沈阳赛区 K. Let the Flames Begin
    2018-2019 ACM-ICPC 徐州区域赛 部分题解
  • 原文地址:https://www.cnblogs.com/weicyNo-1/p/11074307.html
Copyright © 2011-2022 走看看