前言:

无论是Android还是IOS都会使用到多任务,多任务的最小单元那就是线程,今天学习总结一下IOS的NSThread使用。

NSThread使用?

第一种方式实例化

//selector :线程执行的方法,这个selector只能有一个参数,而且不能有返回值。
//target :selector消息发送的对象
//argument:传输给target的唯一参数,也可以是nil
NSThread *newThread = [[NSThread alloc]initWithTarget:self selector:@selector(threadRun) object:nil];

也可以使用另外两种初始化函数

NSThread  *newThread=[[NSThread alloc]init];
NSThread *newThread= [[NSThread alloc]initWithBlock:^{
NSLog(@"initWithBlock");
}];

线程常用的一些属性

    //设置线程名字
[newThread setName:@"thread - 1"];
//设置线程优先级
[newThread setThreadPriority:1.0];
//IOS 8 之后 推荐使用下面这种方式设置线程优先级
//NSQualityOfServiceUserInteractive:最高优先级,用于用户交互事件
//NSQualityOfServiceUserInitiated:次高优先级,用于用户需要马上执行的事件
//NSQualityOfServiceDefault:默认优先级,主线程和没有设置优先级的线程都默认为这个优先级
//NSQualityOfServiceUtility:普通优先级,用于普通任务
//NSQualityOfServiceBackground:最低优先级,用于不重要的任务
[newThread setQualityOfService:NSQualityOfServiceUtility];
//判断线程是否是主线程
[newThread isMainThread];
//线程状态
//是否已经取消
[newThread isCancelled];
//是否已经结束
[newThread isFinished];
//是否正在执行
[newThread isExecuting];

线程启动、取消、暂停

    //线程开始
[newThread start];
//线程取消
[newThread cancel];
//线程暂停
[NSThread sleepForTimeInterval:1.0];
//或者下面这种方式 让线程休眠1秒
[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:1.0]];
//立即终止除主线程以外所有线程
[NSThread exit];

第二种方式类方法

//selector :线程执行的方法,这个selector只能有一个参数,而且不能有返回值。
//target :selector消息发送的对象
//argument:传输给target的唯一参数,也可以是nil
[NSThread detachNewThreadSelector:@selector(doSomething:) toTarget:self withObject:@"lcj"];

上面这种方式创建线程后自动启动线程

获取当前线程

[NSThread currentThread];

获取主线程

 [NSThread mainThread];

第三种方式隐式创建

用于线程之间通信,比如:指定任务在当前线程执行

 //不传递参数指定函数在当前线程执行
[self performSelector:@selector(doSomething)];
//传递参数指定函数在当前线程执行
[self performSelector: @selector(doSomething:) withObject:tempStr];
//传递参数指定函数2秒后在当前线程执行
[self performSelector:@selector(doSomething:) withObject:tempStr afterDelay:2.0];

指定在特定线程执行

//在其他线程中指定在主线程执行
[self performSelectorOnMainThread:@selector(doSomething:) withObject:tempStr waitUntilDone:YES];
//在主线程指定在后台线程执行
[self performSelectorInBackground:@selector(doSomething:) withObject:tempStr];
//在主线程中指定某个特定线程执行
[self performSelector:@selector(doSomething:) onThread:newThread withObject:tempStr waitUntilDone:YES];

线程同步

线程同步就是为了解决多线程同时访问公共共享数据,而导致数据错乱的问题,然后使用同步的方式让公共数据同一时间内只能被一个线程访问来避免数据错乱的问题。

先看下未同步时多线程访问数据错乱问题,首先声明三个线程

    NSThread *thread1=[[NSThread alloc]initWithTarget:self selector:@selector(taskRun) object:nil];
thread1.name=@"thread-1"; NSThread *thread2=[[NSThread alloc]initWithTarget:self selector:@selector(taskRun) object:nil];
thread2.name=@"thread-2"; NSThread *thread3=[[NSThread alloc]initWithTarget:self selector:@selector(taskRun) object:nil];
thread3.name=@"thread-3"; [thread1 start];
[thread2 start];
[thread3 start];

taskRun函数对全部变量count进行操作

-(void)taskRun
{
while (count>) {
[NSThread sleepForTimeInterval:0.1];
count--;
NSLog(@"threadName:%@ count:%d ",[NSThread currentThread].name, count);
}
}

运行结果:

通过上面的数据会发现有明显的错乱问题,导致数据不同步。

实现线程同步的几种方式:

第一种方式@synchronized(对象)关键字

-(void)taskRun
{
while (count>) {
@synchronized(self) { // 需要锁定的代码
[NSThread sleepForTimeInterval:0.1];
count--;
NSLog(@"threadName:%@ count:%d ",[NSThread currentThread].name, count);
}
} }

执行结果

第二种方式NSLock同步锁

首先创建一个NSLock同步锁对象

threadLock=[[NSLock alloc]init];

然后在需要加锁的代码块开始时调用 lock函数 在结束时调用unLock函数

-(void)taskRun
{ while (count>) {
[threadLock lock];
[NSThread sleepForTimeInterval:0.1];
count--;
NSLog(@"threadName:%@ count:%d ",[NSThread currentThread].name, count);
}
[threadLock unlock];
}

第三种方式使用NSCondition同步锁和线程检查器

锁主要为了当检测条件时保护数据源,执行条件引发的任务;线程检查器主要是根据条件决定是否继续运行线程,即线程是否被阻塞。先创建一个NSCondition对象

condition=[[NSCondition alloc]init];

使用同步锁的方式和NSLock相似

-(void)taskRun
{ while (count>) {
[condition lock];
[NSThread sleepForTimeInterval:0.1];
count--;
NSLog(@"threadName:%@ count:%d ",[NSThread currentThread].name, count);
[condition unlock];
} }
NSCondition可以让线程进行等待,然后获取到CPU发信号告诉线程不用在等待,可以继续执行,上述的例子我们稍作修改,我们让线程三专门用于发送信号源
 NSThread *thread1=[[NSThread alloc]initWithTarget:self selector:@selector(taskRun) object:nil];
thread1.name=@"thread-1"; NSThread *thread2=[[NSThread alloc]initWithTarget:self selector:@selector(taskRun) object:nil];
thread2.name=@"thread-2"; NSThread *thread3=[[NSThread alloc]initWithTarget:self selector:@selector(taskRun1) object:nil];
thread3.name=@"thread-3"; [thread1 start];
[thread2 start];
[thread3 start];

taskRun1函数用于发送信号源

-(void)taskRun1
{
while (YES) {
[condition lock];
[NSThread sleepForTimeInterval:];
[condition signal];
[condition unlock];
}
}

taskRun函数 用于执行对count的操作

-(void)taskRun
{ while (count>) {
[condition lock];
[condition wait];
[NSThread sleepForTimeInterval:0.1];
count--;
NSLog(@"threadName:%@ count:%d ",[NSThread currentThread].name, count);
[condition unlock];
} }

执行的结果会发现,只有在Thread-1、和Thread-2 收到信号源的时候才会执行count--,否则一直出于等待状态。

总结:

NSThread属于轻量级多任务实现方式,可以更加只管的管理线程,需要管理线程的生命周期、同步、加锁问题,会导致一定的性能开销,今天简单的了解学习了IOS的NSThread使用,初步对ios线程有所了解。

IOS任务管理之NSThread使用的更多相关文章

  1. iOS GCD NSOperation NSThread等多线程各种举例详解(拷贝)

    2年多的iOS之路匆匆而过,期间也拜读来不少大神的博客,近来突然为自己一直做伸手党感到羞耻,是时候回馈社会.回想当年自己还是小白的时候,照着一些iOS多线程教程学,也只是照抄,只知其然.不知其所以然. ...

  2. [iOS]深入浅出 iOS 之多线程 NSThread

    OS 支持多个层次的多线程 编程,层次越高的抽象程度越高,使用起来也越方便,也是苹果最推荐使用的方法.     下面简要说明这三种不同范式:  Thread 是这三种范式里面相对轻量级的,但也是使用起 ...

  3. IOS任务管理之GCD使用

    前言: 前天学了IOS的NSOperation基本使用,我们得知NSOperation也是基于IOS GCD(Grand Central Dispatch)实现,其实在做IOS开发中GCD已经基本上能 ...

  4. iOS GCD NSOperation NSThread等多线程各种举例详解

    废话就不多说,直接上干货.如下图列举了很多多线程的知识点,每个按钮都写有对应的详细例子,并对运行结果进行分析,绝对拿实践结果来说话.如果各位道友发现错误之处还请指正.附上demo下载地址

  5. iOS 多线程之 NSThread的基本使用

    一个NSThread对象就代表一条线程 下面是NSThread开启线程的方法 - (void)touchesBegan:(NSSet<UITouch *> *)touches withEv ...

  6. iOS 多线程(NSThread、GCD、NSOperation)

    ios中得多线程技术主要使用3种:NSThread.NSOperation和GCD 一.NSThread: 最轻量级方法,但是不安全需要手动加锁,需要自己管理生命周期 NSThread的使用方法有2种 ...

  7. iOS-pthread && NSThread && iOS9网络适配

    几个概念: 进程:"正在运行"应用程序(app)就是一个进程,它至少包含一个线程:            进程的作用:为应用程序开辟内存空间: 线程:CPU调度的最小单元:     ...

  8. IOS UI多线程 NSThread 下载并显示图片到UIImageView

    效果图 @property (weak,nonatomic)IBOutletUILabel *downLabelInfo; @property (weak,nonatomic)IBOutletUIIm ...

  9. IOS多线程(NSThread)

    1.创建方法 使用NSThread创建线程主要有两个个方法,分别如下 NSThread* myThread = [[NSThread alloc] initWithTarget:self   sele ...

随机推荐

  1. jquery在调试时出现缺少对象的错误

    1)引入的js文件出错,  检查方法:将Js的内容写在当前的页面的<script> </script>之间,看是否能够正常运行,如果不能,请核查代码  2) 如果引入的代码在当 ...

  2. iOS设置状态栏的字体颜色

    设置statusBar的[前景色部分] 1.plist设置statusBar 在plist里增加一行 UIStatusBarStyle(或者是“Status bar style”也可以),这里可以设置 ...

  3. Redis详解

    转自:http://blog.csdn.net/eroswang/article/details/7080412 1.  MySql+Memcached架构的问题 1.MySQL需要不断进行拆库拆表, ...

  4. PHP的Cookie、Session和跟Laravel相关的几点了解

    这两天通过对Cookie和Session的查找和了解,网上关于它们两个的基础知识点都是差不多的,也收藏了几篇不错的博客,同时自己做了些实验后,有了以下几点了解: 1.setcookie 这里有三个地方 ...

  5. S3C2440看门狗解析

    个PCLK周期的复位信号 也就是说,在某些环境下,看门狗可以当做定时器使用,当他中断的时候并不发生复位,只发生中断,我看看图 看门狗的中断和复位信号是可以依靠wtcon来切断的(看门狗的时钟是无法切断 ...

  6. HDU 3501 Calculation 2 ——Dirichlet积

    [题目分析] 卷积太有趣了. 最终得出结论,互质数和为n*phi(n)/2即可. 计算(n*(n+1)/2-n-n*phi(n)/2)%md,用反正法即可证明. [代码] #include <c ...

  7. Map笔记

    Map,是一个接口,是以键值对的方式存储的,并且键是无序且不可重复的.Map和Collection没有什么关系,Map是一对一对的存,而Collection是一个一个的存. 下面有一个子接口:Sort ...

  8. onethink插件二(首页图片轮播)

    2014年8月1日 15:34:15 基于slice-box 写了一个图片轮播的插件. 一.功能: 1.图片轮播功能 2.自定义功能(数量,效果,打开方式) 3.多重效果一键切换 4.独立性强,不影响 ...

  9. Object修改链表

    以前学习过链表的时候由于类型的接收不同,每次要重写链表 下面修改可用链表 class Link{ private class Node{ private Object data ; private N ...

  10. Angular - - ngReadonly、ngSelected、ngDisabled

    ngReadonly 该指令将input,textarea等文本输入设置为只读. HTML规范不允许浏览器保存类似readonly的布尔值属性.如果我们将一个Angular的插入值表达式转换为这样的属 ...