NSThread是相对GCD和NSOperationQuene而言,比较轻量级的一种多线程处理方式。

但同时,它的弊端就是需要自己管理线程的生命周期,以及线程同步;而另外两种不需要自己管理。

常见方法介绍:

一、获取当前线程

NSThread *current = [NSThread currentThread];

二、获取主线程

NSThread *main = [NSThread mainThread];

三、NSThread的创建

1 // 初始化线程
2 NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(run:) object:@"aaa"];
3 // 开启线程
4 [thread start];

.静态方法

+ (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)argument;
[NSThread detachNewThreadSelector:@selector(run:) toTarget:self withObject:@""];

执行完上面代码后会马上启动一条新线程,并且在这条线程上调用self的run方法。

.隐式创建线程

[self performSelectorInBackground:@selector(run:) withObject:@""]; 

会隐式地创建一条新线程,并且在这条线程上调用self的run方法。

四、暂停当前线程

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

上面两种做法都是暂停当前线程2秒

退出线程

[NSThread exit]; 

五、线程的其他操作

1.在指定线程上执行操作

1 [self performSelector:@selector(run) onThread:thread withObject:nil waitUntilDone:YES]; 

* 上面代码的意思是在thread这条线程上调用self的run方法

* 最后的YES代表:上面的代码会阻塞,等run方法在thread线程执行完毕后,上面的代码才会通过

2.在主线程上执行操作

[self performSelectorOnMainThread:@selector(run) withObject:nil waitUntilDone:YES];  

在主线程调用self的run方法

3.在当前线程执行操作

[self performSelector:@selector(run) withObject:nil]; 

在当前线程调用self的run方法

场景1:

异步下载一张图片,下载完在UI显示。

代码实现:

//开启子线程下载
[NSThread detachNewThreadSelector:@selector(downloadPic) toTarget:self withObject:nil]; //下载图片
-(void)downloadPic{
NSURL *url = [NSURL URLWithString:@"https://res.wx.qq.com/mpres/htmledition/images/mp_qrcode218877.gif"];
NSData *pic = [NSData dataWithContentsOfURL:url];
UIImage *img = [UIImage imageWithData:pic];
//回到主线程显示
[self performSelectorOnMainThread:@selector(showImg:) withObject:img waitUntilDone:YES];
} -(void)showImg:(UIImage *)image{
//imageView.image = image
NSLog(@"显示 pic");
}

  

六、多线程安全与加锁

   说明:多线程访问同一个资源的时候可能会出现数据错乱等安全问题,解决方法是对必要的代码段进行加锁。

   注意:在OC中加互斥锁使用@synchronized(self) {},在swift可以使用objc_sync_enter(self)和objc_sync_exit(self)方法,注意这两个方法必须成对使用,把要加锁的代码放在中间.

场景1:

以售票为例:3个售票员同时售票,票总数为10。

- (void)sailTicket {
NSThread *thread1 = [[NSThread alloc] initWithTarget:self selector:@selector(sale) object:nil];
NSThread *thread2 = [[NSThread alloc] initWithTarget:self selector:@selector(sale) object:nil];
NSThread *thread3 = [[NSThread alloc] initWithTarget:self selector:@selector(sale) object:nil];
thread1.name = @"售票员1";
thread2.name = @"售票员2";
thread3.name = @"售票员3";
[thread1 start];
[thread2 start];
[thread3 start]; } -(void)sale{
while () {
@synchronized (self) {
for (int i = ; i<; i++) {
//模拟延迟
} if (_ticketCount>){
_ticketCount--;
NSLog(@"%@卖出了一张票,余票还有%lu",[NSThread currentThread].name,(unsigned long)_ticketCount);
}else{
NSLog(@"票已售完");
break;
}
}
} }

可以很明显看出,每个售票员都是严格按照从10递减的方式售票,不存在票数忽多忽少的情况。

如果不加锁:

  

iOS 多线程NSThread理解与场景示例的更多相关文章

  1. iOS多线程 NSThread/GCD/NSOperationQueue

    无论是GCD,NSOperationQueue或是NSThread, 都没有线程安全 在需要同步的时候需要使用NSLock或者它的子类进行加锁同步 "] UTF8String], DISPA ...

  2. ios多线程NSThread

    1.简介: 1.1 iOS有三种多线程编程的技术,分别是: 1..NSThread 2.Cocoa NSOperation (iOS多线程编程之NSOperation和NSOperationQueue ...

  3. iOS多线程NSThread和GCD

    在iOS中啊  其实有多种方法实现多线程 这里只记录两个比较常用的  或者说我比较常用的 一个就是BSThread 另一个就是一听名字就比较霸气的妇孺皆知的GCD 先说一下NSThread吧 这个方式 ...

  4. iOS 多线程之线程锁Swift-Demo示例总结

    线程锁是什么 在前面的文章中总结过多线程,总结了多线程之后,线程锁也是必须要好好总结的东西,这篇文章构思的时候可能写的东西得许多,只能挤时间一点点的慢慢的总结了,知道了线程之后要了解线程锁就得先了解一 ...

  5. IOS 多线程 NSThread

    一个正在运行的应用程序是一个进程,一个进程会默认开启一个主线程,但是在主线程中的操作是串行的,也就是当有多个任务同时需要完成的时候,是按照顺序一个个执行.因此,为了提高效率,会在进程中开启多个线程,每 ...

  6. IOS 多线程-NSThread 和线程状态

    @interface HMViewController () - (IBAction)btnClick; @end @implementation HMViewController - (void)v ...

  7. iOS多线程的详情使用示例--简进祥

    大家都知道,在开发过程中应该尽可能减少用户等待时间,让程序尽可能快的完成运算.可是无论是哪种语言开发的程序最终往往转换成汇编语言进而解释成机器码来执行.但是机器码是按顺序执行的,一个复杂的多步操作只能 ...

  8. iOS多线程开发

    概览 大家都知道,在开发过程中应该尽可能减少用户等待时间,让程序尽可能快的完成运算.可是无论是哪种语言开发的程序最终往往转换成汇编语言进而解释成机器码来执行.但是机器码是按顺序执行的,一个复杂的多步操 ...

  9. iOS 多线程详解

    iOS开发 多线程 概览 机器码是按顺序执行的,一个复杂的多步操作只能一步步按顺序逐个执行.改变这种状况可以从两个角度出发: 对于单核处理器,可以将多个步骤放到不同的线程,这样一来用户完成UI操作后其 ...

随机推荐

  1. IFeatureLayer

      All Properties Methods Inherited Non-inherited Description AreaOfInterest The default area of inte ...

  2. 无源RS232转RS485(转)

    源:无源RS232转RS485 RS232  -485转换器主要包括了电源.232电平转换.485电路三部分.本电路的232电平转换电路采用了NIH232或者也可以直接使用MAX232集成电路,485 ...

  3. 控制流之for

    for..in是另外一个循环语句,它在一序列的对象上 递归 即逐一使用队列中的每个项目.我们会在后面的章节中更加详细地学习序列.使用for语句~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ...

  4. lpc1768的PWM使用

    //p2.0 pwm1.1 void ALS_Init(void)     //初始化 { LPC_SC->PCONP |= (1<<1)|(1<<2)|(1<&l ...

  5. IIS日志路径,修改存放位置,清除日志方法

    IIS存放日志文件的默认存储路径是c:\windows\system32\logfiles 我们依次打开“我的电脑”,C盘,Windows文件夹,system32文件夹,logfiles文件夹,发现里 ...

  6. IIS Default Web Site : The service did not response to the start or control request in a timely fashion

    IIS Default Web Site无法启动,提示错误:The service did not response to the start or control request in a time ...

  7. ARM的启动代码(1):介绍(转)

    源:ARM的启动代码(1):介绍 很多朋友搞嵌入式,写起代码来一点问题没有,到最后上板子调试的时候,挂了.究其原因,还是对芯片的启动地址.启动方式.bootloader和操作系统的衔接出了问题.今天就 ...

  8. 浅谈IOS8之size class

    文章目录 1. 简介 2. 实验 3. 实战 3.1. 修改 Constraints 3.2. 安装和卸载 Constraints 3.3. 安装和卸载 View 3.4. 其他 4. 后话 以前和安 ...

  9. Vue.js使用前

    下载安装 node,npm,git 安装cnpm 淘宝cnpm镜像https://npm.taobao.org/,-g表示进行全局安装 npm install -g cnpm --registry=h ...

  10. 【转】C\C++代码优化的27个建议

    1. 记住阿姆达尔定律: funccost是函数func运行时间百分比,funcspeedup是你优化函数的运行的系数. 所以,如果你优化了函数TriangleIntersect执行40%的运行时间, ...