iOS:多线程NSThread的详细使用
NSThread具体使用:直接继承NSObject
FOUNDATION_EXPORT NSString * const NSWillBecomeMultiThreadedNotification;
FOUNDATION_EXPORT NSString * const NSDidBecomeSingleThreadedNotification;
+ (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(id)argument;
※是否是多线程
+ (BOOL)isMultiThreaded;
※定时休眠
+ (void)sleepUntilDate:(NSDate *)date;
※休眠时间
+ (void)sleepForTimeInterval:(NSTimeInterval)ti;
※退出线程
+ (void)exit;
※线程优先级
+ (double)threadPriority;
※设置线程优先级
+ (BOOL)setThreadPriority:(double)p;
※显示当前栈内容(返回的是这个线程在栈中所占的地址所组成的数组)
+ (NSArray *)callStackReturnAddresses;
※返回栈空间的符号
+ (NSArray *)callStackSymbols;
※是否是主线程
+ (BOOL)isMainThread;
※创建线程的实例方法,并添加执行事件
- (instancetype)initWithTarget:(id)target selector:(SEL)selector object:(id)argument;
※取消线程
- (void)cancel;
※启动线程
- (void)start;
※线程主体要执行的方法 :thread body method
- (void)main;
4、类别:@interface NSObject (NSThreadPerformAdditions)
※调用主线程,传入一个与主线程RunLoop循环执行有关的数组
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait modes: (NSArray *)array;
※调用主线程更新UI
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
※调用指定的线程,传入一个与线程RunLoop循环执行有关的数组
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait modes:(NSArray *)array;
※调用指定的线程更新数据
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone: (BOOL)wait;
※在后台调用线程
- (void)performSelectorInBackground:(SEL)aSelector withObject:(id)arg;
具体举例如下:多线程卖票(要求:把当前票数和当前线程的名字显示在文本视图上)
1.在控件工具中拖拽一个文本视图控件并与类相关联
@property (weak, nonatomic) IBOutlet UITextView *textView; //拖拽一个文本视图控件并与类关联
2.准备数据,并将文本视图中默认的内容置空
//准备资源
_tickets = ; //将默认文本视图中的内容置空
self.textView.text = @""; //取消自动布局,用来控制文本视图的滚动
self.textView.layoutManager.allowsNonContiguousLayout = NO;
3.创建两个线程买票
//创建两个线程并启动线程
//售票线程-1
NSThread *thread1 = [[NSThread alloc]initWithTarget:self selector:@selector(saleTicket) object:nil];
//设置线程的名字,以区别不同的线程
[thread1 setName:@"售票线程-1"];
//启动线程
[thread1 start]; //售票线程-2
NSThread *thread2 = [[NSThread alloc]initWithTarget:self selector:@selector(saleTicket) object:nil];
//设置线程的名字,以区别不同的线程
[thread2 setName:@"售票线程-2"];
//启动线程
[thread2 start];
4.为主线程创建一个方法,专门用来更新并显示UI的
#pragma mark -更新UI
-(void)appendTextView:(NSString *)text
{
//1.获取textView中已有的内容
NSMutableString *stringM = [[NSMutableString alloc]initWithString:self.textView.text]; //2.追加新的内容
[stringM appendString:[NSString stringWithFormat:@"\n%@",text]];
[self.textView setText:stringM]; //3.调节焦点,滚动视图
NSRange range = NSMakeRange(stringM.length, );
[self.textView scrollRangeToVisible:range];
}
5.为买票线程创建一个方法,负责买票
#pragma mark -卖票的过程
在方法-(void)saleTicket
{
while (YES) {
执行代码如下:
}
}
//当票数大于0时,即if(_tickets>0)时,
操作数据并更新UI为:
//并发执行时,采用同步代码块加锁,防止数据在一个线程的操作过程中被另一个线程抢占篡改,锁必须是唯一的
@synchronized(self)
{
//拼接字符串(当前数据信息)
NSString *str = [NSString stringWithFormat:@"当前票数:%d 当前线程:%@",_tickets,[[NSThread currentThread]name ]];
//调用主线程,更新UI
[self performSelectorOnMainThread:@selector(appendTextView:) withObject:str waitUntilDone:YES];
_tickets--;
}
进行休眠为:
//休眠一段时间,模拟耗时操作
if([[[NSThread currentThread]name] isEqualToString:@"售票线程-1"])
{
[NSThread sleepForTimeInterval:0.3f];
}
else
{
[NSThread sleepForTimeInterval:0.2f];
}
//当票数小于或等于0时,更新UI,并结束线程
//拼接字符串(当前数据信息)
NSString *str = [NSString stringWithFormat:@"票已经卖完 当前线程:%@",[[NSThread currentThread]name]]; //调用主线程,更新UI
[self performSelectorOnMainThread:@selector(appendTextView:) withObject:str waitUntilDone:YES]; break; //结束while死循环,结束线程
演示结果如下:

当然,上面采用的是同步代码块隐式处理线程同步的问题,还可以采用显式加锁的方式来防止数据同步。
首先,声明一个NSLock的锁对象
@property (strong,nonatomic)NSLock *lock;
然后将上面的@synchronized(self)代码做修改,如下:
//在访问竞争资源前加锁
[self.lock lock]; //拼接字符串(当前数据信息)
NSString *str = [NSString stringWithFormat:@"当前票数:%d 当前线程:%@",_tickets,[[NSThread currentThread]name]]; //调用主线程,更新UI
[self performSelectorOnMainThread:@selector(appendTextView:) withObject:str waitUntilDone:YES];
_tickets--; //访问完竞争资源马上解锁
[self.lock unlock];
演示结果相同:

iOS:多线程NSThread的详细使用的更多相关文章
- iOS多线程 NSThread/GCD/NSOperationQueue
无论是GCD,NSOperationQueue或是NSThread, 都没有线程安全 在需要同步的时候需要使用NSLock或者它的子类进行加锁同步 "] UTF8String], DISPA ...
- ios多线程NSThread
1.简介: 1.1 iOS有三种多线程编程的技术,分别是: 1..NSThread 2.Cocoa NSOperation (iOS多线程编程之NSOperation和NSOperationQueue ...
- iOS多线程NSThread和GCD
在iOS中啊 其实有多种方法实现多线程 这里只记录两个比较常用的 或者说我比较常用的 一个就是BSThread 另一个就是一听名字就比较霸气的妇孺皆知的GCD 先说一下NSThread吧 这个方式 ...
- IOS 多线程 NSThread
一个正在运行的应用程序是一个进程,一个进程会默认开启一个主线程,但是在主线程中的操作是串行的,也就是当有多个任务同时需要完成的时候,是按照顺序一个个执行.因此,为了提高效率,会在进程中开启多个线程,每 ...
- iOS 多线程NSThread理解与场景示例
NSThread是相对GCD和NSOperationQuene而言,比较轻量级的一种多线程处理方式. 但同时,它的弊端就是需要自己管理线程的生命周期,以及线程同步:而另外两种不需要自己管理. 常见方法 ...
- IOS 多线程-NSThread 和线程状态
@interface HMViewController () - (IBAction)btnClick; @end @implementation HMViewController - (void)v ...
- iOS多线程的详情使用示例--简进祥
大家都知道,在开发过程中应该尽可能减少用户等待时间,让程序尽可能快的完成运算.可是无论是哪种语言开发的程序最终往往转换成汇编语言进而解释成机器码来执行.但是机器码是按顺序执行的,一个复杂的多步操作只能 ...
- iOS多线程开发
概览 大家都知道,在开发过程中应该尽可能减少用户等待时间,让程序尽可能快的完成运算.可是无论是哪种语言开发的程序最终往往转换成汇编语言进而解释成机器码来执行.但是机器码是按顺序执行的,一个复杂的多步操 ...
- iOS 多线程详解
iOS开发 多线程 概览 机器码是按顺序执行的,一个复杂的多步操作只能一步步按顺序逐个执行.改变这种状况可以从两个角度出发: 对于单核处理器,可以将多个步骤放到不同的线程,这样一来用户完成UI操作后其 ...
随机推荐
- 【转载】viewLoad、viewDidLoad的一些事
viewLoad和viewDidLoad都可以用来在视图载入的时候,初始化一些内容 viewDidLoad此方法只有当view从nib文件初始化的时候才被调用.viewDidLoad用于初始化,加载时 ...
- elasticsearch更新license
Elasticsearch更新license: 初次安装Marvel,有30天的使用时间,当到期后,只保存7天的数据,所以需要注册申请一个license: 注册申请地址: https://regist ...
- PHP PDO类
<?php //数据库连接类,不建议直接使用DB,而是对DB封装一层 //这个类不会被污染,不会被直接调用 class DB { //pdo对象 private $_pdo = null; // ...
- 解决获取图片实际尺寸(宽高)的bug
需求:获取图片的宽高其实是为了预先做好排版样式布局做准备. 可以利用图片onload事件监听获取图片的宽高属性值.在IE9以下版本只能使用图片的width与height属性,HTMl5中新加入了nat ...
- getAllResponseHeaders() 必须放到onload里面
<html><head> <meta charset="utf-8"> <title>test</title> < ...
- react native android应用启动画面
参考地址:https://www.youtube.com/watch?v=rnLR65OGtic 第一步:生成启动画面的背景图片 生成一个2048*2048的背景图片,打开网站https://apet ...
- HZAU 1205 Sequence Number(双指针)
题目链接:http://acm.hzau.edu.cn/problem.php?id=1205 [题意]给你一串数,要求你找到两个数a[i],a[j],使得a[i]<=a[j]且j>=i且 ...
- CSS 笔记——盒子模型
2. 盒子模型 在CSS眼中,任何HTML标签对象都是一个矩形,有长度,宽度以及各角的定位坐标,俗称CSS 盒子模型理论. Margin(外边距) - 清除边框外的区域,外边距是透明的. Border ...
- lightoj 1244 - Tiles 状态DP
思路:状态DP dp[i]=2*dp[i-1]+dp[i-3] 代码如下: 求出循环节部分 1 #include<stdio.h> 2 #define m 10007 3 int p[m] ...
- bootstrapTable定位行固定滚动条
写在前面: 当页面table列表数据有修改后,用户需要再次回到修改的行位置. 1.当修改行数据后,table刷新,行数据位置前后不发生改变 ,可使用下面这种方法: /*获取当前滚动条的位置*/ var ...