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. Android学习笔记之Intent(1)

    1.Intent指定启动目标组件 2.Intentfilter描述基本组件所在地址 3.其他包引入资源文件时记得引入R所在的包 package com.jikexueyuan.intent; impo ...

  2. uvc摄像头代码解析1

    一.FAQ 1.判断自己的摄像头是否支持uvc标准 输入lsusb //列出usb设备 [cpp]   Bus 001 Device 001: ID 1d6b:0002 Linux Foundatio ...

  3. Keil C动态内存管理机制分析及改进(转)

    源:Keil C动态内存管理机制分析及改进 Keil C是常用的嵌入式系统编程工具,它通过init_mempool.mallloe.free等函数,提供了动态存储管理等功能.本文通过对init_mem ...

  4. nexus 中央仓库

    nexus 中央仓库 下载地址:http://www.sonatype.org/nexus/archived 下载最新版本 mkdir -p /opt/local/nexus tar zxvf nex ...

  5. JOSN反串行化

    JOSN编码的数据可以使用eval函数生产操作的类型. <%@ Page Language="C#" %> <!DOCTYPE html PUBLIC " ...

  6. SVN第二篇-----命令集合

    16.switch  代码库URL变更 svn switch (sw): 更新工作副本至不同的URL. 用法:  1.switch URL [PATH]         更新你的工作副本,映射到一个新 ...

  7. ANSI标准

    NSI:美国国家标准学会(AMERICAN NATIONAL STANDARDS INSTITUTE: ANSI)成立于1918年.当时,美国的许多企业和专业技术团体,已开始了标准化工作,但因彼此间没 ...

  8. LPC2478的GPIO使用详解

    GPIO使用 LPC2478的GPIO是不能断开时钟的,上电就连接.处理GPIO主要就下面几步 1.      设置为普通IO模式 2.      设置输入输出方向 3.      设置值 以下寄存器 ...

  9. LIBPNG

    libpng 库的源码包中有个 example.c ,里面包含PNG文件读/写的示例代码,参考示例代码和注释(虽然是英文的),可以了解大致的用法. 以下是读取PNG图片的图像数据的代码,使用前还需要按 ...

  10. matlab取模与取余

    mod函数采用floor,rem函数采用fix函数.那么什么是floor和fix? fix(x):截尾取整.如: >> fix([3.4 , -3.4]) ans = 3 -3 floor ...