读书笔记 多线程 -- NSThread
2019-05-30 本文已影响0人
_桃夭大人_
NSThread 是传统意义上底层pthread线程的OC封装
优点:
- 设置线程的服务质量Qos
- 可以设置线程堆大小
- 线程提供local数据字典,可以存储key/value数据
- 实时性更高
- 与RunLoop结合,提供更为灵活高效的线程管理方式
缺点:
- 创建线程代时,需要同时占用应用和内核的内存空间(GCD只占用内核的内存空间)
- 编写线程相关代码相对繁杂
1.线程的创建方式
// 1.
[NSThread detachNewThreadWithBlock:^{
NSLog(@"NSThread");
}];
// 2.
[NSThread detachNewThreadSelector:@selector(dosomething:) toTarget:self withObject:data];
// 3.
NSThread * thread = [[NSThread alloc]initWithTarget:self selector:@selector(dosomething:) object:data];
thread.name = @"thread1";
[thread start];
// 4. 子类化NSThread
// 重载main方法实现子类化,加上自动释放池确保线程处理过程中及时释放内存资源。
- (void)main{
@autoreleasepool {
// 线程处理
}
}
2.NSTread类的属性和方法
// 获取当前线程
@property (class, readonly, strong) NSThread *currentThread;
// 是否支持多线程
+ (BOOL)isMultiThreaded;
// 线程本地的数据字典
@property (readonly, retain) NSMutableDictionary *threadDictionary;
// 休眠到指定的日期
+ (void)sleepUntilDate:(NSDate *)date;
// 定期休眠
+ (void)sleepForTimeInterval:(NSTimeInterval)ti;
// 退出线程
+ (void)exit;
// 线程的优先级
+ (double)threadPriority;
// 设置线程的优先级
+ (BOOL)setThreadPriority:(double)p;
// 线程服务质量
@property NSQualityOfService qualityOfService ; // read-only after the thread is started
// 堆栈返回地址
@property (class, readonly, copy) NSArray<NSNumber *> *callStackReturnAddresses ;
// 堆栈调用链
@property (class, readonly, copy) NSArray<NSString *> *callStackSymbols ;
// 线程的名字
@property (nullable, copy) NSString *name ;
// 堆栈的大小
@property NSUInteger stackSize ;
// 是否是主线程
@property (readonly) BOOL isMainThread ;
@property (class, readonly, strong) NSThread *mainThread;
// 是否正在执行
@property (readonly, getter=isExecuting) BOOL executing ;
// 是否已完成
@property (readonly, getter=isFinished) BOOL finished ;
// 是否取消
@property (readonly, getter=isCancelled) BOOL cancelled ;
// 取消执行
- (void)cancel ;
// 开始执行
- (void)start;
// 线程执行的主方法,子类化线程时需要 重载这个方法
- (void)main; // thread body method
3.NSObject线程扩展方法
// 在主线程执行方法
- (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 API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(nullable id)arg waitUntilDone:(BOOL)wait API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
// 后台线程执行方法
- (void)performSelectorInBackground:(SEL)aSelector withObject:(nullable id)arg API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
4.线程中的共享资源保护
4.1. OSAtomic 原子操作 更轻量级,性能更高。
4.2.加锁
(1)NSLock 互斥锁
NSLock * theLock = [[NSLock alloc]init];
if ([theLock tryLock]) {// 尝试获取锁,不会阻塞当前任务的执行
NSLog(@"读写");
[theLock unlock];
}
(2)NSRecursiveLock 递归锁
主要用在 循环或者递归操作中,保证同一个线程执行多次加锁操作不会产生死锁,只要保证加锁和解锁的次数相同,就能释放资源使其他线程得到资源使用。
NSRecursiveLock * recursive = [[NSRecursiveLock alloc]init];
for (int i = 0; i < 10; i ++) {
[recursive lock];
NSLog(@"读写操作");
[recursive unlock];
}
(3)NSConditionLock条件锁
condition为一个整数参数
当condition的值满足时 可以获得锁;
解锁时可以设置condition条件;
lockWhenCondition:表示condition为参数值时 获得锁
unlockWithCondition: 表示解锁并设置condition的值
4.3. NSCondition
通过一些条件控制多线程执行任务,当条件不满足时线程等待;条件满足时通过发送signal信号等待线程 继续处理
NSCondition * condition = [[NSCondition alloc]init];
[condition lock];
if (0) {
// 如果条件不满足 等待
[condition wait];
}else{
// 条件满足,发送信号
[condition signal];
}
[condition unlock];
4.4.@synchronized 同步指令
synchronized是自动实现加锁技术的,同时增加了异常处理。
编译器自动插入加锁和解锁的代码,同时捕获异常避免异常时不能及时释放锁,导致死锁。
@synchronized (self){
// do something
}
来自 《macOS应用开发基础教程 张帆》读书笔记