读书笔记 多线程 -- NSThread

2019-05-30  本文已影响0人  _桃夭大人_

NSThread 是传统意义上底层pthread线程的OC封装
优点:

缺点:

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应用开发基础教程 张帆》读书笔记

上一篇下一篇

猜你喜欢

热点阅读