美文网首页
iOS 多线程(二)-NSThread

iOS 多线程(二)-NSThread

作者: 搬砖的crystal | 来源:发表于2021-05-28 21:29 被阅读0次

NSThread适合轻量级的多线程开发,控制线程顺序比较难,同时线程总数无法控制(每次创建并不能重用之前的线程,只能创建新的线程)

1.初始化
- (void)viewDidLoad {
    [super viewDidLoad];
    //方法一,需要start
    NSThread *thread1 = [[NSThread alloc]initWithTarget:self selector:@selector(threadAction:) object:@"thread1"];
    [thread1 start];
    //方法二,需要start
    NSThread *thread2 = [[NSThread alloc]initWithBlock:^{
        NSLog(@"thread2 - %@",[NSThread currentThread]);
    }];
    [thread2 start];
    //方法三
    [NSThread detachNewThreadSelector:@selector(threadAction:) toTarget:self withObject:@"thread3"];
}

-(void)threadAction:(NSString *)string{
    NSLog(@"%@ - %@",string,[NSThread currentThread]);
}
//输出结果
2021-05-28 20:49:04.539618+0800 DJGCDDemo[1077:23059] thread2 - <NSThread: 0x6000018f0bc0>{number = 9, name = (null)}
2021-05-28 20:49:04.539612+0800 DJGCDDemo[1077:23058] thread1 - <NSThread: 0x6000018f0180>{number = 8, name = (null)}
2021-05-28 20:49:04.539633+0800 DJGCDDemo[1077:23060] thread3 - <NSThread: 0x6000018f0a80>{number = 10, name = (null)}
2.属性
/**
每个线程都维护了一个键-值的字典,它可以在线程里面的任何地方被访问。
你可以使用该字典来保存一些信息,这些信息在整个线程的执行过程中都保持不变。
比如,你可以使用它来存储在你的整个线程过程中Run loop里面多次迭代的状态信息。
NSThread实例可以使用一下方法
*/
@property (readonly, retain) NSMutableDictionary *threadDictionary;
/**
 优先级
 */
@property double threadPriority ;
/** NSQualityOfService:
  NSQualityOfServiceUserInteractive:最高优先级,主要用于提供交互UI的操作,比如处理点击事件,绘制图像到屏幕上
  NSQualityOfServiceUserInitiated:次高优先级,主要用于执行需要立即返回的任务
  NSQualityOfServiceDefault:默认优先级,当没有设置优先级的时候,线程默认优先级
  NSQualityOfServiceUtility:普通优先级,主要用于不需要立即返回的任务
  NSQualityOfServiceBackground:后台优先级,用于完全不紧急的任务
*/
@property NSQualityOfService qualityOfService;
/**
 线程名称
 */
@property (nullable, copy) NSString *name;
/**
 线程使用栈区大小,默认是512K
 */
@property NSUInteger stackSize ;
/**
 线程正在执行
 */
@property (readonly, getter=isExecuting) BOOL executing;
/**
 线程执行结束
 */
@property (readonly, getter=isFinished) BOOL finished;
/**
 线程是否可以取消
 */
@property (readonly, getter=isCancelled) BOOL cancelled;
3.实例方法
/**
 启动线程
 */
-(void)start;
/**
 是否为主线程
 */
-(BOOL)isMainThread;
/**
 取消线程
 */
-(void)cancel;
/**
 线程的入口函数
 */
-(void)main;
/**
 判断线程是否正在执行
 */
-(void)isExecuting;
/**
 判断线程是否已经结束
 */
-(void)isFinished;
/**
 判断线程是否撤销
 */
-(void)isCancelled;
4.类方法
/**
  block方式
*/
+ (void)detachNewThreadWithBlock:(void (^)(void))block;
/**
  SEL方式
*/
+ (void)detachNewThreadSelector:(SEL)selector toTarget:(id)target withObject:(nullable id)argument;
/**
 获取当前线程
 */
+(void)currentThread;
/**
 当前代码运行所在线程是否是子线程
 */
+(BOOL)isMultiThreaded;
/**
 前代码所在线程睡到指定时间
 */
+(void)sleepUntilDate:(NSDate *)date;
/**
 当前线程睡多长时间
 */
+(void)sleepForTimeInterval:(NSTimeInterval)ti;
/**
 退出当前线程
 */
+(void)exit;
/**
 设置当前线程优先级
 */
+(double)threadPriority;
/**
 给当前线程设定优先级,调度优先级的取值范围是0.0 ~ 1.0,默认0.5,值越大,优先级越高
 */
+(BOOL)setThreadPriority:(double)p;
/**
 线程的调用都会有函数的调用函数的调用就会有栈返回地址的记录,在这里返回的是函 数调用返回的虚拟地址,说白了就是在该线程中函数调用的虚拟地址的数组
 */
+(NSArray *)callStackReturnAddresses;
/**
 同上面的方法一样,只不过返回的是该线程调用函数的名字数字
 */
+(NSArray *)callStackSymbols;

callStackReturnAddresscallStackSymbols这两个函数可以同NSLog联合使用来跟踪线程的函数调用情况,是编程调试的重要手段

5.隐式创建

以下方法位于NSObject (NSThreadPerformAdditions)分类中,所有继承NSObject 实例化对象都可调用以下方法。

/**
指定方法在主线程中执行
参数1. SEL方法
   2.方法参数
   3.是否等待当前执行完毕
   4.指定的Runloop model
*/
- (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;
/**
指定方法在某个线程中执行
参数1. SEL方法
   2.方法参数
   3.是否等待当前执行完毕
   4.指定的Runloop model
*/
- (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));
/**
指定方法在开启的子线程中执行
参数1. SEL 方法
   2.方法参数
*/
- (void)performSelectorInBackground:(SEL)aSelector withObject:(nullable id)arg API_AVAILABLE(macos(10.5), ios(2.0), watchos(2.0), tvos(9.0));
6.线程间通信

NSThread靠NSObject分类的方法实现线程间通信。

- (void)viewDidLoad {
    [super viewDidLoad];

    NSThread *thread1 = [[NSThread alloc]initWithBlock:^{
        NSLog(@"thread1 - %@",[NSThread currentThread]);
        //回到主线程更新UI
        [self performSelectorOnMainThread:@selector(updateUI) withObject:self waitUntilDone:YES];
    }];
    [thread1 start];
}
-(void)updateUI{
    NSLog(@"回到主线程更新UI - %@",[NSThread currentThread]);
}
//输出结果
2021-05-28 21:28:35.548572+0800 DJGCDDemo[1361:48398] thread1 - <NSThread: 0x600000336880>{number = 8, name = (null)}
2021-05-28 21:28:35.552002+0800 DJGCDDemo[1361:48233] 回到主线程更新UI - <NSThread: 0x600000374a40>{number = 1, name = main}

相关文章

网友评论

      本文标题:iOS 多线程(二)-NSThread

      本文链接:https://www.haomeiwen.com/subject/hosssltx.html