什么是线程?什么是进程?线程和进程什么关系?这不是我们这一章关心的重点,我在这里假设大家都知道线程是cpu调度的最小单位,进程是cpu资源分配的最小单位,一个进程可以有若干个线程,为什么会这样,这也不是我们的重点,我还是假设大家都知道了cpu效率太高,需要的资源准备太慢,如果等待就太浪费cpu,所以我们让cpu每隔一段时间(非常短)就去做别的事情,然后一直切换,这就是所谓的多线程。
iOS中多线程有几种?GCD、NSOperation这两种大家都是能脱口而出的,也是大家最常用的两种,对iOS稍微了解多点的都知道还有NSThread,这个就很少使用了,因为要手动管理生命周期,其实iOS还有一种多线程应用方式,就是Pthread,这个大家知道有这么个东西就好,去百度一下随便看看,内容正式开始
Pthread
直接百度就可以了,没什么好说的
POSIX线程(POSIX threads),简称Pthreads,是线程的POSIX标准。该标准定义了创建和操纵线程的一整套API。在类Unix操作系统(Unix、Linux、Mac OS X等)中,都使用Pthreads作为操作系统的线程。Windows操作系统也有其移植版pthreads-win32。
NSTread
并不常用,了解一下,看下里面方法的功能
初始化一个线程
//创建线程并绑定fun方法
NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(fun) object:nil];
启动一个线程
//创建并启动线程,执行fun方法
[NSThread detachNewThreadSelector:@selector(fun) toTarget:self withObject:nil];
[thread start];//启动线程
//如果你子类化NSThread类,你可以重写main方法,并且实现它。如果你这样做,你就没有必要调用super。
你绝不能直接调用mian方法,你应该通过调用start方法启动你的线程。
如果直接调用好像是会在主线程执行selectior方法
[thread main];
停止一个线程
[NSThread sleepForTimeInterval:3];// 阻塞线程一定的时间
[NSThread sleepUntilDate:[NSDate dateWithTimeIntervalSinceNow:3.0]];//阻塞线程直到某个时间
[NSThread exit];//杀死当前线程
[thread cancel];//取消线程
线程的状态
@property (readonly, getter=isExecuting) BOOL executing;//线程的执行状态
@property (readonly, getter=isFinished) BOOL finished;//线程的完成状态
@property (readonly, getter=isCancelled) BOOL cancelled;//线程的取消状态
活动在主线程
@property (readonly) BOOL isMainThread;//判断是否在主线程;
@property(class, readonly) BOOL isMainThread;//判断当前线程是否在主线程
@property(class, readonly, strong) NSThread *mainThread;//返回主线程
线程环境
+ (BOOL)isMultiThreaded;//当前程序是否是多线程的
@property(class, readonly, strong) NSThread *currentThread;//返回当前所在线程
//返回现场调用的地址数组
@property(class, readonly, copy) NSArray<NSNumber *> *callStackReturnAddresses;
+ (NSArray *)callStackSymbolsNS_AVAILABLE(10_6,4_0); //返回现场调用的名字数组
线程属性
@property(readonly, retain) NSMutableDictionary *threadDictionary;//存储数据的字典
@property(copy) NSString *name;//线程的名字
@property NSUInteger stackSize;//存储空间大小
线程优先级
+ (double)threadPriority;//返回当前线程优先级
@property double threadPriority;//设置或者获取当前线程优先级
+ (BOOL)setThreadPriority:(double)p;//设置当前线程优先级
下面还有几个通知就不写了,看名字就知道什么意思.
还有一些object基于NSTread实现的方法
@interface NSObject (NSThreadPerformAdditions)
@interface NSObject (NSThreadPerformAdditions)
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(nullable id)arg waitUntilDone:(BOOL)wait modes:(nullable NSArray<NSString *> *)array;
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(nullable id)arg waitUntilDone:(BOOL)wait;
// equivalent to the first method with kCFRunLoopCommonModes
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(nullable id)arg waitUntilDone:(BOOL)wait modes:(nullable NSArray<NSString *> *)array NS_AVAILABLE(10_5, 2_0);
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(nullable id)arg waitUntilDone:(BOOL)wait NS_AVAILABLE(10_5, 2_0);
// equivalent to the first method with kCFRunLoopCommonModes
- (void)performSelectorInBackground:(SEL)aSelector withObject:(nullable id)arg NS_AVAILABLE(10_5, 2_0);
还有一些新加入的方法
- (instancetype)initWithBlock:(void (^)(void))block;//初始化一个带有block的线程
+ (void)detachNewThreadWithBlock:(void (^)(void))block;//创建一个带有block的线程并立即执行
系统要求
iOS 10.0+
macOS 10.12+
tvOS 10.0+
watchOS 3.0+
还有一个系统优先级的方法,是一个枚举类型
//可读写属性,但是在线程开始之后就变成只读属性
@property NSQualityOfService qualityOfService;
typedef NS_ENUM(NSInteger, NSQualityOfService) {
NSQualityOfServiceUserInteractive = 0x21,
NSQualityOfServiceUserInitated = 0x19,
NSQualityOfServiceUtility = 0x11,
NSQualityOfServiceBackground = 0x09,
NSQualityOfServiceDefault = -1
} NS_ENUM_AVAILABLE(10_10, 8_0);
系统要求
iOS 8.0+
macOS 10.10+
tvOS 8.0+
watchOS 2.0+
- UserInteractive:UserInteractive 用于直接参与提供一个交互式UI,如处理事件或对屏幕的绘制。
- UserInitiated:UserInitiated 用于表示执行工作已经被用户显示提出并且要求结果能够立即展示以便进行进一步的用户交互。比如:用户在信息列表点击之后立即加载一个email。
- Utility:Utility 用于表述执行一项工作后,用户并不需要立即得到结果。这一工作通常用户已经请求过或者在初始化的时候已经自动执行,不会阻碍用户用户的进一步交互,通常在用户可见的时间尺度和可能由一个非模态的进度指示器展示给用户。
- Background:Background 用于那些非用户初始化或可见的工作。通常说来,用户甚至不知道这想工作已经发生,但是它会以最有效的方法运行,用于完全不紧急的任务。例如:内容抓取,搜索索引,备份,同步与外部系统的数据。
- Default:默认的优先级。尽可能的从其它资源推断可能的优先级信息。如果这一推断不成立,一个位于UserInitiated和Utility之间的优先级将得以使用。