IOS开发入门之NSThread概念及使用教程
凌雪 2018-10-23 来源 :网络 阅读 981 评论 0

摘要:本文将带你了解IOS开发入门iOS多线程之NSThread概念及使用教程,希望本文对大家学IOS有所帮助。

本文将带你了解IOS开发入门iOS多线程之NSThread概念及使用教程,希望本文对大家学IOS有所帮助。


       

iOS多线程之NSThread概念及使用教程。

组织架构说明

本系列文章是按照相关多线程类的抽象层次撰写的,也就是说NSThread是Foundation框架提供的最基础的多线程类,每一个NSThread类的对象即代表一个线程,接下来苹果为开发者封装了GCD(Grand   Central   Dispatch),GCD相比于NSThread来说,提供了便捷的操作方法,开发者不需要再关注于管理线程的生命周期,也不需要自行管理一个线程池用于线程的复用,但GCD是以C函数对外提供接口,因此Foundation框架在GCD的基础上进行了面向对象的封装,提供了面向对象的多线程类NSOperation和NSOperationQueue,抽象层次更高。

由于OC是C语言的超集,开发者也可以选择使用POSIX标准的线程pthread,pthread和NSThread都是对内核mach   kernel的mach   thread的封装,所以在开发时一般不会使用pthread。

RunLoop是与线程相关的一个基本组成,想要线程在执行完任务后不退出,在没有任务时睡眠以节省CPU资源都需要RunLoop的实现,因此,正确的理解线程就需要深入理解RunLoop相关知识。

NSThread的使用姿势全解

在组织架构说明中讲到,NSThread是对内核mach   kernel中的mach   thread的封装,所以,每一个NSThread的对象其实就是一个线程,我们创建一个NSThread对象也就意味着我们创建了一个新的线程。初始化创建NSThread的方法有如下几种:



   

<code><code><code><code><code><code><code><code><code><code><code><code>/*

使用target对象的selector作为线程的任务执行体,该selector方法最多可以接收一个参数,该参数即为argument

*/

-   (instancetype)initWithTarget:(id)target selector:(SEL)selector   object:(nullable id)argument API_AVAILABLE(macos(10.5), ios(2.0),   watchos(2.0),   tvos(9.0));

 

/*

使用block作为线程的任务执行体

*/

-   (instancetype)initWithBlock:(void (^)(void))block API_AVAILABLE(macosx(10.12), ios(10.0),   watchos(3.0),   tvos(10.0));

 

/*

类方法,返回值为void

使用一个block作为线程的执行体,并直接启动线程

上面的实例方法返回NSThread对象需要手动调用start方法来启动线程执行任务

*/

+   (void)detachNewThreadWithBlock:(void (^)(void))block API_AVAILABLE(macosx(10.12), ios(10.0),   watchos(3.0),   tvos(10.0));

 

/*

类方法,返回值为void

使用target对象的selector作为线程的任务执行体,该selector方法最多接收一个参数,该参数即为argument

同样的,该方法创建完县城后会自动启动线程不需要手动触发

*/

+   (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target   withObject:(nullable   id)argument;</code></code></code></code></code></code></code></code></code></code></code></code>

   

下面分别举几个栗子:



<code><code><code><code><code><code><code><code><code><code><code><code>/*

说明:   本文的栗子都是在单视图的工程中执行,防止主线程退出后,其他线程被退出,不方便实验。

*/

 

//线程的任务执行体并接收一个参数arg

- (void)firstThread:(id)arg

{

    for (int i   = 0; i   < 10;   i++)

    {

        NSLog(@"Task %@ %@", [NSThread currentThread],   arg);

    }

    NSLog(@"Thread Task Complete");

}

 

-   (void)viewWillAppear:(BOOL)animated

{     

    [super viewWillAppear: YES];

 

    /*

    创建一个线程,线程任务执行体为firstThread:方法

    该方法可以接收参数@"Hello, World"

    */

    NSThread *thread = [[NSThread alloc]   initWithTarget:self selector:@selector(firstThread:) object:@"Hello, World"];

    //设置线程的名字,方便查看

    [thread setName:@"firstThread"];

    //启动线程

    [thread start];     

}

 

- (void)viewDidAppear:(BOOL)animated

{

    [super viewDidAppear: YES];

    NSLog("ViewDidAppear");

}</code></code></code></code></code></code></code></code></code></code></code></code>

   

上面的栗子没有什么实际意义,仅仅为了展示如何创建并启动线程,启动程序后就可以看到程序输出了10次

 

<code><code><code><code><code><code><code><code><code><code><code><code>Task   <nsthread: 0x1c446f780="">{number = 4, name   = firstThread} Hello,   World</nsthread:></code></code></code></code></code></code></code></code></code></code></code></code>

   

上面输出了线程的名称,还输出了我们传入的参数,通过很简单的代码就可以创建一个新的线程来执行任务,在开发中尽量将耗时的操作放在其他线程中执行,只将更新UI的操作放在主线程中执行。

一般情况下,通过上述方法创建的线程在执行完任务执行体后就会退出并销毁,可以在firstThread:方法的第二个NSLog方法和viewDidAppear:方法的输出上打断点,然后运行程序查看线程信息,在第一个断点时即firstThread:方法的断点中,程序中线程信息如下图:

从上图可以看到,现在程序中有一个线程名为firstThread,该线程即为我们创建的NSThread对象,而com.apple.main-thread(serial)即为主线程的名称,其中serial是指明主线程是串行的,这个内容会在GCD中进行讲解,我们可以通过类方法[NSThread   mainThread]来获取主线程。接下来继续执行到第二个断点,程序中线程信息如下图:

从上图可以看到,firstThread线程不见了,因为在执行完任务执行体后该线程就退出并被销毁了,

通过这个栗子也说明了,我们无法复用NSThread,尽管线程的创建相比进程更加轻量级,但创建一个线程远比创建一个普通对象要消耗资源,而主线程和接收事件处理的线程仍然存在,这正是因为RunLoop的作用,这个内容也会在RunLoop部分进行讲解。

接下来继续讲解创建NSThread的其他方法,具体如下:


<code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code>//2:

/*

通过传入block的方式创建一个线程,线程执行体即为block的内容

但该方式创建线程无法传入参数

*/

NSThread   *thread = [[NSThread alloc] initWithBlock:^{

    for (int i   = 0; i < 100; i++)

    {

        NSLog(@"Task %@", [NSThread currentThread]);

    }

}];

//设置线程名称

[thread setName:@"firstThread"];

//启动线程

[thread start];

 

//3:

/*

通过类方法创建并自动启动一个线程

该线程的执行体即为传入的block

*/

[NSThread   detachNewThreadWithBlock:^{

    for (int i   = 0; i   < 100; i++)

    {

        NSLog(@"Task %@", [NSThread currentThread]);

    }

}];

 

//4:

/*

通过类方法创建并自动启动一个线程

该线程的执行体为self的firstThread:方法,并传入相关参数

*/

[NSThread detachNewThreadSelector:@selector(firstThread:) toTarget:self   withObject:@"Hello, World!"];</code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code></code>

   

上述把所有NSThread的创建方法都讲解了一遍,实例方法和类方法的区别就在于,实例方法会返回NSThread对象,当需要启动线程时需要手动触发start方法,而类方法没有返回值,创建线程后立即启动该线程。这里说的启动线程start方法,仅仅是将线程的状态从新建转为就绪,何时执行该线程的任务需要系统自行调度。

接下来再看NSThread中几个比较常用的属性和方法:


   

<code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code><code>/*

类属性,用于获取当前线程

如果是在主线程调用则返回主线程对象

如果在其他线程调用则返回其他的当前线程

什么线程调用,就返回什么线程

*/

@property (class,   readonly, strong) NSThread *currentThread;

 

//类属性,用于返回主线程,不论在什么线程调用都返回主线程

@property (class,   readonly, strong) NSThread *mainThread;

 

/*

设置线程的优先级,范围为0-1的doule类型,数字越大优先级越高

我们知道,系统在进行线程调度时,优先级越高被选中到执行状态的可能性越大

但是我们不能仅仅依靠优先级来判断多线程的执行顺序,多线程的执行顺序无法预测

*/

@property double threadPriority;

 

//线程的名称,前面的栗子已经介绍过了

@property (nullable, copy) NSString *name

 

//判断线程是否正在执行

@property (readonly, getter=isExecuting) BOOL   executing;

 

//判断线程是否结束

@property   (readonly, getter=isFinished) BOOL   finished;

 

//判断线程是否被取消

@property (readonly,   getter=isCancelled) BOOL cancelled;

 

   

   

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之IOS频道!

本文由 @凌雪 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程