iOS开发多线程之NSThread
一、NSThread的属性与方法
1.NSThread 类方法
类方法,顾名思义通过类名直接调用的方法
1. + (void)detachNewThreadWithBlock:(void (^)(void))block
本方法适用于 ios(10.0),线程的创建,线程创建后直接运行,使用示例如下:
[self detachNewThreadWithBlock:^{
//想要实现的功能
NSLog(@“currentThread:%@”,[NSThread currentThread]);
}];
2. + (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(nullable id)argument;
本方法适用于 ios(10.0)之前版本,线程的创建,线程创建后直接运行,使用示例如下:
[self detachNewThreadSelector:@Selector(用此线程执行的函数) toTarget:self withObject:@“想要传入的参数”];
3. + (NSThread *)mainThread; // 获得主线程
使用示例:NSThread *myMainThread=[NSThread mainThread];
4. + (BOOL)isMainThread; // 判断当前线程是否是主线程
使用示例:BOOL isMain=[NSThread isMainThread];
5. + (BOOL)isMultiThreaded;//判断当前线程是否是多线程
使用示例:BOOL isMulti=[NSThread isMultiThreaded];
6. + (void)sleepUntilDate:(NSDate *)date;//当前线程休眠到指定日期
使用示例:NSDate *myDate=[NSDate dateWithTimeInterval:5 sinceDate:[NSDate date]];
[NSThread sleepUntilDate:myDate];
7. + (void)sleepForTimeInterval:(NSTimeInterval)ti;//当前线程休眠指定时常
使用示例:[NSThreadsleepForTimeInterval:5];
8. + (void)exit;//强行退出当前线程
使用示例:[NSThreadexit];
9. + (double)threadPriority;//获取当前线程线程优先级
使用示例:double dPriority=[NSThread threadPriority];
10. + (BOOL)setThreadPriority:(double)p;//给当前线程设定优先级,调度优先级的取值范围是0.0 ~ 1.0,默认0.5,值越大,优先级越高。
使用示例:BOOL isSetting=[NSThread setThreadPriority:(0.0~1.0)];
11. + (NSArray *)callStackReturnAddresses //线程的调用都会有函数的调用函数的调用就会有栈返回地址的记录,在这里返回的是函 数调用返回的虚拟地址,说白了就是在该线程中函数调用的虚拟地址的数组
使用示例:NSArray* addressArray=[NSThread callStackReturnAddresses];
12.+ (NSArray *)callStackSymbols //同上面的方法一样,只不过返回的是该线程调用函数的名字数字
使用示例:NSArray* nameNumArray=[NSThread callStackSymbols];
注意:callStackReturnAddress和callStackSymbols这两个函数可以同NSLog联合使用来跟踪线程的函数调用情况,是编程调试的重要手段
2.NSthread 实例方法
实例方法,顾名思义通过类对象实例调用的方法
1. - (instancetype)initWithBlock:(void (^)(void))block
本方法适用于 ios(10.0),线程创建之后等待开始命令在开始运行,使用示例如下:
NSThread *exampleThread=[NSThread alloc]initWithBlock:^{
//想要实现的功能
NSLog(@“currentThread:%@”,[NSThread currentThread]);
}]
[exampleThread start];
2. - (instancetype)initWithTarget:(id)target selector:(SEL)selector object:(nullable id)argument
本方法适用于 ios(10.0)之前版本,线程创建之后等待开始命令在开始运行,使用示例如下:
NSThread *exampleThread = [[NSThread alloc] initWithTarget:self selector:@selector(用此线程执行的函数) object:@“想要传入的参数”];
[exampleThread start];
3.- (BOOL)isMainThread; // 是否为主线程
使用示例:BOOL isMain=[exampleThreadisMainThread];
4.- (void)setName:(NSString *)n;//设置线程名称
使用示例:[exampleThread setName=@"叶阳"];
5. - (void)cancel ;//取消线程
使用示例:[exampleThread cancel];
6. - (void)start ;//开始执行
使用示例:[exampleThreadstart];
7. - (void)main ;//线程的入口函数
使用示例:[exampleThreadmain];
8. -(void)isExecuting;//判断线程是否正在执行
使用示例:BOOL isRunning=[exampleThread isExecuting];
9. -(void)isFinished;//判断线程是否已经结束
使用示例:BOOL isEnd=[exampleThread isFinished];
10. -(void)isCancelled;//判断线程是否撤销
使用示例:isCancel=[exampleThreadisCancelled];
3.NSObject类的扩展
1.- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(nullable id)arg waitUntilDone:(BOOL)waitmodes:(nullable NSArray<NSString *> *)array;
在主线程上执行函数,wait表示是否阻塞该方法,等待主线程空闲再运行,modes表示运行模式
使用示例:[selfperformSelectorOnMainThread:@Selector(要运行的函数) withObject:@"想要传入的参数" waitUntilDone:(BOOL)wait modes:(nullable NSArray<NSString *> *)array];
2.- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(nullable id)arg waitUntilDone:(BOOL)wait;
本函数与上一个函数的kCFRunLoopCommonModes运行模式相同
使用示例:[selfperformSelectorOnMainThread:@Selector(要运行的函数) withObject:@"想要传入的参数" waitUntilDone:(BOOL)wait];
3.- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(nullable id)arg waitUntilDone:(BOOL)wait modes:(nullable NSArray<NSString *> *)array
在指定线程上执行函数,wait表示是否阻塞该方法,等待指定线程空闲再运行,modes表示运行模式
使用示例:[selfperformSelector:@Selector(要运行的函数) onThread:(自己指定的线程)withObject:@"想要传入的参数" waitUntilDone:(BOOL)wait modes:(nullable NSArray<NSString *> *)array];
4.- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(nullable id)arg waitUntilDone:(BOOL)wait
本函数与上一个函数的kCFRunLoopCommonModes运行模式相同
使用示例:[selfperformSelector:@Selector(要运行的函数) onThread:(自己指定的线程)withObject:@"想要传入的参数" waitUntilDone:(BOOL)wait];
5.- (void)performSelectorInBackground:(SEL)aSelector withObject:(id)arg
本函数是隐式创建一个线程并执行
使用示例: [self performSelectorInBackground:@Selector(要运行的函数) withObject:@"想要传入的参数"];
4.NSthread的属性
1.@property (readonly, retain) NSMutableDictionary *threadDictionary;//线程字典
2.@property double threadPriority ; //优先级
3.@property NSQualityOfService qualityOfService ; //线程优先级
NSQualityOfServiceUserInteractive:最高优先级,主要用于提供交互UI的操作,比如处理点击事件,绘制图像到屏幕上
NSQualityOfServiceUserInitiated:次高优先级,主要用于执行需要立即返回的任务
NSQualityOfServiceDefault:默认优先级,当没有设置优先级的时候,线程默认优先级
NSQualityOfServiceUtility:普通优先级,主要用于不需要立即返回的任务
NSQualityOfServiceBackground:后台优先级,用于完全不紧急的任务
4.@property (nullable, copy) NSString *name;线程名称
5.@property NSUInteger stackSize ;//线程使用栈区大小,默认是512K
6.@property (readonly, getter=isExecuting) BOOL executing;//线程正在执行
7.@property (readonly, getter=isFinished) BOOL finished;//线程执行结束
8.@property (readonly, getter=isCancelled) BOOL cancelled;//线程是否可以取消
5.NSThread有三个线程相关的通知
NSWillBecomeMultiThreadedNotification:由当前线程派生出第一个其他线程时发送,一般一个线程只发送一次
NSDidBecomeSingleThreadedNotification:这个通知目前没有实际意义,可以忽略
NSThreadWillExitNotification线程退出之前发送这个通知
二、线程锁
线程锁的使用,主要是为了防止多个线程对同一个对象做操作,造成混乱和错误。
NSLock / NSConditionLock / NSRecursiveLock / @synchronized
线程锁大都遵循NSLocking协议,这个协议提供了两个线程锁的基本函数
- (void)lock;//加锁
- (void)unlock;//解锁
1.NSLock
- (BOOL)tryLock;//尝试加锁,成功返回YES ;失败返回NO ,但不会阻塞线程的运行
- (BOOL)lockBeforeDate:(NSDate *)limit;
//在指定的时间以前得到锁。YES:在指定时间之前获得了锁;NO:在指定时间之前没有获得锁。
该线程将被阻塞,直到获得了锁,或者指定时间过期。
- (void)setName:(NSString*)newName//为锁指定一个Name
- (NSString*)name//返回锁指定的name
@property (nullable, copy) NSString *name;线程锁名称
使用示例:
NSLock* myLock=[[NSLock alloc]init];
NSString *str=@"hello";
[NSThread detachNewThreadWithBlock:^{
[myLock lock];
NSLog(@"%@",str);
str=@"world";
[myLock unlock];
}];
[NSThread detachNewThreadWithBlock:^{
[myLock lock];
NSLog(@"%@",str);
str=@"变化了";
[myLock unlock];
}];
输出结果不加锁之前,两个线程输出一样 hello;加锁之后,输出分辨为hello 与world。
2.NSConditionLock
使用此锁,在线程没有获得锁的情况下,阻塞,即暂停运行,典型用于生产者/消费者模型。
- (instancetype)initWithCondition:(NSInteger)condition;//初始化条件锁
- (void)lockWhenCondition:(NSInteger)condition;//加锁 (条件是:锁空闲,即没被占用;条件成立)
- (BOOL)tryLock; //尝试加锁,成功返回TRUE,失败返回FALSE
- (BOOL)tryLockWhenCondition:(NSInteger)condition;//在指定条件成立的情况下尝试加锁,成功返回TRUE,失败返回FALSE
- (void)unlockWithCondition:(NSInteger)condition;//在指定的条件成立时,解锁
- (BOOL)lockBeforeDate:(NSDate *)limit;//在指定时间前加锁,成功返回TRUE,失败返回FALSE,
- (BOOL)lockWhenCondition:(NSInteger)condition beforeDate:(NSDate *)limit;//条件成立的情况下,在指定时间前加锁,成功返回TRUE,失败返回FALSE,
@property (readonly) NSInteger condition;//条件锁的条件
@property (nullable, copy) NSString *name;//条件锁的名称
使用示例:
NSConditionLock* myCondition=[[NSConditionLock alloc]init];
[NSThread detachNewThreadWithBlock:^{
for(int i=0;i<5;i++)
{
[myCondition lock];
NSLog(@"当前解锁条件:%d",i);
sleep(2);
[myCondition unlockWithCondition:i];
BOOL isLocked=[myCondition tryLockWhenCondition:2];
if(isLocked)
{
NSLog(@"加锁成功!!!!!");
[myCondition unlock];
}
}
}];
输出结果,在条件2 解锁之后,等待条件2 的锁加锁成功。
3. NSRecursiveLock
此锁可以在同一线程中多次被使用,但要保证加锁与解锁使用平衡,多用于递归函数,防止死锁。
- (BOOL)tryLock;//尝试加锁,成功返回TRUE,失败返回FALSE
- (BOOL)lockBeforeDate:(NSDate *)limit;//在指定时间前尝试加锁,成功返回TRUE,失败返回FALSE
@property (nullable, copy) NSString *name;//线程锁名称
使用示例:
-(void)initRecycle:(int)value
{
[myRecursive lock];
if(value>0)
{
NSLog(@"当前的value值:%d",value);
sleep(2);
[self initRecycle:value-1];
}
[myRecursive unlock];
}
输出结果: 从你传入的数值一直到1,不会出现死锁
4.@synchronized
@synchronized指令做和其他互斥锁一样的工作(它防止不同的线程在同一时间获取同一个锁)
@synchronized(线程共同使用的对象){
多个线程使用同一个Obj,都会判断Obj是否已被占用,Obj空闲则用,繁忙则等待
}
使用示例:
NSString *str=@"hello";
for(int i=0;i<2;i++)
{
[NSThread detachNewThreadWithBlock:^{
@synchronized (str) {
NSLog(@"thread.name:%@------str:%@",str);
str=@"world";
}
}];
}
iOS开发多线程之NSThread的更多相关文章
- iOS开发-多线程之GCD(Grand Central Dispatch)
Grand Central Dispatch(GCD)是一个强有力的方式取执行多线程任务,不管你在回调的时候是异步或者同步的,可以优化应用程序支持多核心处理器和其他的对称多处理系统的系统.开发使用的过 ...
- iOS开发多线程之NSOperation
NSInvocationOperation The NSInvocationOperationclass is a concrete subclass of NSOperationthat you u ...
- iOS开发多线程之GCD
Grand Central Dispatch(GCD)是异步执行任务的技术之一.一般将应用程序中记述的线程管理用的代码在系统级中实现.开发者只需要定义想执行的任务并追加到适当的Dispatch Que ...
- 多线程之NSThread
关于多线程会有一系列如下:多线程之概念解析 多线程之pthread, NSThread, NSOperation, GCD 多线程之NSThread 多线程之NSOperation 多线程之GCD一, ...
- iOS开发之多线程(NSThread、NSOperation、GCD)
整理一些多线程相关的知识. 并行 & 并发 1.并行:并行是相对于多核而言的,几个任务同时执行.2.并发:并发是相对于单核而言的,几个任务之间快速切换运行,看起来像是"同时" ...
- iOS开发笔记5:多线程之NSThread、NSOperation及GCD
这篇主要总结下iOS开发中多线程的使用,多线程开发一般使用NSThread.NSOperation及GCD三种方式,常用GCD及NSOperation. 1.NSThread 创建线程主要有以下三种方 ...
- iOS多线程之NSThread使用
iOS中的多线程技术 我们在iOS开发项目过程中,为了解决UI界面操作不被耗时操作阻塞,我们会使用到多线程技术.在iOS开发中,我们主要会用到三种多线程操作技术:NSThread,NSOperatio ...
- iOS多线程之NSThread详解
在iOS中每个进程启动后都会建立一个主线程(UI线程),这个线程是其他线程的父线程.由于iOS中除了主线程,其他子线程是独立于Cocoa Touch的,所以只有主线程可以更新UI界面.iOS多线程的使 ...
- iOS-多线程之NSThread详解
前言 线程是用来执行任务的,线程彻底执行完任务A才能去执行任务B.为了同时执行两个任务,产生了多线程. 我打开一个视频软件,我开辟一个线程A让它执行下载任务,我开辟一个线程B,用来播放视频.我开辟两个 ...
随机推荐
- PHP整洁之道
摘录自 Robert C. Martin的Clean Code 书中的软件工程师的原则 ,适用于PHP. 这不是风格指南. 这是一个关于开发可读.可复用并且可重构的PHP软件指南. 并不是这里所有的原 ...
- git中如何撤销部分修改?
以提问中修改了两个文件a.b为例,假设需要撤销文件a的修改,则修改后的两个文件: 1.如果没有被git add到索引区 git checkout a 便可撤销对文件a的修改 2.如果被git add到 ...
- js01-javascript语法标准和数据类型
语法规则 (1)JavaScript对换行.缩进.空格不敏感. 备注:每一条语句末尾要加上分号,虽然分号不是必须加的,但是为了程序今后要压缩,如果不加分号,压缩之后将不能运行. (2)所有的符号,都是 ...
- c指针作业(第一次)
1. 数据类型的本质是什么? (从编译器的角度考虑) 数据类型可理解为创建变量的模具:是固定内存大小的别名 数据类型的作用:编译器预算对象(变量)分配的内存空间大小 注意:数据类型只是模具,编译器并没 ...
- Python——装饰器
1.装饰器形成的过程 2.装饰器的作用 3.原则:开放封闭原则 开放:对扩展是开放的 封闭:对修改是封闭的 4.装饰器的固定模式 def func(): time.sleep(0.01) ') def ...
- Linux 学习 (十一) 软件安装管理
Linux软件安装管理 学习笔记 软件包简介 软件包分类: 源码包 :脚本安装包 二进制包(RPM 包.系统默认包) 源码包的优点: 开源,如果有足够的能力,可以修改源代码 可以自由选择所需的功能 软 ...
- Flask 视图,中间件
视图 FBV def index(nid): """ 请求相关信息 request.method # 请求方式 request.args # get 方式的参数获取 re ...
- 【转】如何在 GitHub 上找到你要的代码?
[来源]
- CF1059D Nature Reserve
原题链接 网络不好的可以到洛谷上去QwQ 题目大意 有N个点,求与y=0相切的,包含这N个点的最小圆的半径 输入输出样例 输入: 2 0 1 1 1 输出 0.625 感觉最多是蓝题难度? 首先无解的 ...
- qt: 获取sql数据表的所有的字段;
1. mysql 数据库: 转载: https://www.cnblogs.com/fuqia/p/8994080.html mysql安装成功后可以看到已经存在mysql.information_s ...