IOS多线程之NSThread

NSThread

如果GCD是面对任务队列来操作多线程,那么NSThread就是直接面对线程来实现多线程的了。

生成和使用线程

NSThread生成线程有以下两种方法:

  • - initWithTarget:selector:object:
  • + detachNewThreadSelector:toTarget:withObject:
NSThread *mainThread = [NSThread mainThread];
NSLog(@"main thread address:%p",mainThread);

NSThread *subThread1 = [[NSThread alloc] initWithTarget:self selector:@selector(method) object:nil];
//也可以用[NSThread detachNewThreadSelector:@selector(method) toTarget:self withObject:nil];

[subThread1 start];//用initWithTarget:selector:object:生成线程以后要调用start才开启线程
-(void)method{
    NSLog(@"hello");
    NSLog(@"subthread address:%p",[NSThread currentThread]);
}

运行结果:

2018-09-07 15:28:29.221983+0800 Test[4550:925375] main thread address:0x28266b6c0
2018-09-07 15:28:29.222226+0800 Test[4550:925429] hello
2018-09-07 15:28:29.222243+0800 Test[4550:925429] subthread address:0x282608280

NSThread是一种轻量级的方法操作线程,实现的方法也很容易,值得注意的是,调用了start以后也未必是立马就执行处理,只是线程处于就绪状态,当系统调度到了才会执行。
另外,根据苹果文档,initWithTarget:selector:object:和detachNewThreadSelector:toTarget:withObject:的target和argument会在执行处理的时候retain,直到线程退出才会被release,注意,不是处理执行完才被release

停止或阻塞线程

  1. 线程阻塞(休眠):+ sleepUntilDate:+ sleepForTimeInterval:
    sleepUntilDate:是使当前线程休眠到某个指定的时间点,sleepForTimeInterval是使当前线程休眠一段时间。
  2. 线程取消:- cancel
    调用cancel的意义和NSOperation的cancel一致,线程会有一个cancelled的属性,调用该函数会改变该属性,线程会周期性的检查是否已经调用过该方法,如果是,则会退出线程。
  3. 线程退出:+ exit
    调用exit会currentThread来获取当前线程,在线程即将退出时,会发出NSThreadWillExitNotification的消息给default notification center,相关的观察者会收到该消息。值得注意的是,如果你想清理所有该线程在执行时分配的所有资源,就不该调用exit
@interface MyThread : NSThread

@end

@implementation MyThread

-(void)dealloc{
    NSLog(@"MyThread dealloc");
}

@end
MyThread *thread = [[MyThread alloc] initWithTarget:self selector:@selector(method) object:nil];
[thread start];
-(void)method{
    NSLog(@"thread sleeping started");
    [NSThread sleepForTimeInterval:3];
    NSLog(@"thread sleeping finished");
    [[NSThread currentThread] exit];
    NSLog(@"thread cancelled");
    //    [NSThread exit];
    //    NSLog(@"thread exited");
}

运行结果:

2018-09-07 16:23:25.912243+0800 Test[4596:938690] thread sleeping started
2018-09-07 16:23:28.919540+0800 Test[4596:938690] thread sleeping finished
2018-09-07 16:23:28.919694+0800 Test[4596:938690] thread cancelled
2018-09-07 16:23:28.920188+0800 Test[4596:938690] MyThread dealloc

再换成exit:

-(void)method{
    NSLog(@"thread sleeping started");
    [NSThread sleepForTimeInterval:3];
    NSLog(@"thread sleeping finished");
//    [[NSThread currentThread] cancel];
//    NSLog(@"thread cancelled");
    [NSThread exit];
    NSLog(@"thread exited");
}

运行结果:

2018-09-07 16:28:17.646135+0800 Test[4602:940012] thread sleeping started
2018-09-07 16:28:20.649485+0800 Test[4602:940012] thread sleeping finished
2018-09-07 16:28:20.650322+0800 Test[4602:940012] MyThread dealloc

从上面两个运行结果可以发现:
1、即便线程处于休眠时调用cancel或者exit,都不会退出,因为此时线程处于阻塞状态,要等到阻塞状态结束才会退出。
2、从thread cancelled有打印,而thread exited没有打印可以知道,cancel的调用系统还不会立刻回收线程,线程过一会才退出;而调用exit系统会立刻回收线程。

其他API

  1. isMainThread:判断是否在主线程。
  2. mainThread:获取主线程对象。
  3. currentThread:获取当前线程对象。
  4. setThreadPriority:设置线程优先级,0.0到1.0,1.0为最大优先级。设置成功会返回YES,否则是NO。

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