iOS 多线程 --- NSThread

一. NSThread开启新的线程

1. 创建并启动线程

NSThread *thread = [[NSThread alloc] initWithTarget:self selector:@selector(loadData) object:nil];
[thread start];

- (void)loadData{
    NSLog(@"%@", [NSThread currentThread]);
}
{number = 3, name = (null)}

2. 创建并启动线程

[NSThread detachNewThreadSelector:@selector(loadData) toTarget:self withObject:nil];

- (void)loadData{
    NSLog(@"%@", [NSThread currentThread]);
}
{number = 3, name = (null)}

3. 隐式创建线程并启动

[self performSelectorInBackground:@selector(loadData) withObject:nil];

- (void)loadData{
    NSLog(@"%@", [NSThread currentThread]);
}
{number = 3, name = (null)}

二. NSThread多线程常用相关方法

1. 线程属性相关

// 获得主线程
+ (NSThread *)mainThread;    
// 判断是否为主线程(对象方法)
- (BOOL)isMainThread;
// 判断是否为主线程(类方法)
+ (BOOL)isMainThread;    
// 获得当前线程
NSThread *thread = [NSThread currentThread];
// 线程的名字——setter方法
- (void)setName:(NSString *)n;    
// 线程的名字——getter方法
- (NSString *)name; 

2. 线程状态控制相关

// 线程进入就绪状态 -> 运行状态。当线程任务执行完毕,自动进入死亡状态
// 启动线程方法
- (void)start;

// 阻塞(暂停)线程方法 
// 线程进入阻塞状态
+ (void)sleepUntilDate:(NSDate *)date;
+ (void)sleepForTimeInterval:(NSTimeInterval)ti;

// 强制停止线程
// 线程进入死亡状态
+ (void)exit;

3. 线程执行操作相关

// 在主线程上执行操作
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait;
- (void)performSelectorOnMainThread:(SEL)aSelector withObject:(id)arg waitUntilDone:(BOOL)wait modes:(NSArray *)array;
  // equivalent to the first method with kCFRunLoopCommonModes

// 在指定线程上执行操作
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait modes:(NSArray *)array NS_AVAILABLE(10_5, 2_0);
- (void)performSelector:(SEL)aSelector onThread:(NSThread *)thr withObject:(id)arg waitUntilDone:(BOOL)wait NS_AVAILABLE(10_5, 2_0);

// 在当前线程上执行操作,调用 NSObject 的 performSelector:相关方法
- (id)performSelector:(SEL)aSelector;
- (id)performSelector:(SEL)aSelector withObject:(id)object;
- (id)performSelector:(SEL)aSelector withObject:(id)object1 withObject:(id)object2;

三. NSThread线程之间的通信

先开一个新的子线程执行耗时操作,然后回到主线程中刷新UI。

[NSThread detachNewThreadSelector:@selector(loadData) toTarget:self withObject:nil];

- (void)loadData{
    NSLog(@"1.%@", [NSThread currentThread]);
    [NSThread sleepForTimeInterval:2.0];
    [self performSelectorOnMainThread:@selector(reloadUI) withObject:nil waitUntilDone:YES];
}
- (void)reloadUI{
    NSLog(@"2.%@", [NSThread currentThread]);
}
 1.{number = 3, name = (null)}
 2.{number = 1, name = main}

四. 线程安全

需求:有时候,我们会在多个地方同时对同一个接口进行调用,那如果每次调用过程会对下一次调用的结果有影响(有修改或者更变等操作),那么我们就必须保证该接口同一时间只能被一个地方调用,这就是线程安全

- (void)viewDidLoad {
    [super viewDidLoad];
    for (int i = 0; i < 10; i ++) {
        [NSThread detachNewThreadSelector:@selector(loadData) toTarget:self withObject:nil];
    }
}
- (void)loadData{
    @synchronized (self) {
        // 模拟耗时操作
        [NSThread sleepForTimeInterval:1.0];
        NSLog(@"---");
    }
}

注:@synchronized的作用是创建一个互斥锁,这个指令可以将{ }内的代码限制在一个线程执行,如果某个线程没有执行完,其他的线程如果需要执行就得等着,起到线程的保护作用。

五. 线程状态总结

iOS 多线程 --- NSThread_第1张图片
线程状态图.png
  • 当线程创建之后被启动,进入就绪状态
  • 当线程被CPU调度,进入运行状态
  • CPU去调度其他线程,回到就绪状态
  • CPU在运行当前线程对象的时候调用了sleep方法或者等待同步锁,进入阻塞状态。等到sleep到时或者得到同步锁,则回到就绪状态
  • CPU在运行当前线程对象的时候线程任务执行完毕或者异常强制退出,则当前线程对象进入死亡状态

你可能感兴趣的:(iOS 多线程 --- NSThread)