小知识,大挑战!本文正在参与“程序员必备小知识”创作活动。
1. 简介
NSthread是苹果官方提供面向对象的线程操作技术,是对thread的上层封装,比较偏向于底层。简单方便,可以直接操作线程对象,使用频率较少。
创建线程的三种方式:
- 通过init初始化方式创建,开辟线程,启动线程。
detach分离,不需要启动,直接分离出新的线程执行。- 隐式的多线程调用方法,没有
thread,也没有start。所属NSObject的NSThreadPerformAdditions分类。
- (void)creatThreadMethod{
NSLog(@"%@", [NSThread currentThread]);
//方式一:
NSThread *t = [[NSThread alloc] initWithTarget:self.p selector:@selector(study:) object:@100];
t.name = @"学习线程";
[t start];
//方式二:
[NSThread detachNewThreadSelector:@selector(study:) toTarget:self.p withObject:@10000];
//方式三:
[self.p performSelectorInBackground:@selector(study:) withObject:@5000];
NSLog(@"%@", [NSThread currentThread]);
}
1.1 属性
- name:在应用程序中,收集错误日志,能够记录工作的线程。否则不好判断具体哪一个线程出的问题\
- stackSize:该值必须以字节为单位,且为4KB的倍数\
- isExecuting:线程是否在执行\
- isCancelled:线程是否被取消\
- isFinished:是否完成\
- isMainThread:是否是主线程\
- threadPriority:线程的优先级,取值范围0.0-1.0,默认优先级0.5。1.0表示最高优先级,优先级高CPU调度的频率高\
- qualityOfService:服务质量,替代threadPriority属性\
- (void)testThreadProperty{
// 主线程 512K
NSLog(@"NSThread:%@,stackSize:%zdK,isMainThread:%d", [NSThread currentThread], [NSThread currentThread].stackSize / 1024, [NSThread currentThread].isMainThread);
NSThread *t = [[NSThread alloc] initWithTarget:self selector:@selector(eat) object:nil];
t.name = @"吃饭线程";
t.stackSize = 1024*1024;
t.threadPriority = 1;
[t start];
}
-------------------------
//输出以下内容:
NSThread:<NSThread: 0x281014600>{number = 1, name = main},stackSize:512K,isMainThread:1
1.2 类方法
currentThread:获取当前线程sleepForTimeInterval:阻塞线程exit:退出线程mainThread:获取主线程
- (void)threadTest{
//当前线程
[NSThread currentThread];
// 如果返回值为1,表示主线程,否则是子线程
NSLog(@"%@", [NSThread currentThread]);
//阻塞休眠
[NSThread sleepForTimeInterval:2];//休眠时长,单位秒
[NSThread sleepUntilDate:[NSDate date]];//休眠到指定时间
//退出线程
[NSThread exit];
//判断当前线程是否为主线程
[NSThread isMainThread];
//判断当前线程是否是多线程
[NSThread isMultiThreaded];
//主线程的对象
NSThread *mainThread = [NSThread mainThread];
NSLog(@"%@", mainThread);
}
1.3 exit & cancel
exit:一旦强行终止线程,后续的所有代码都不会执行cancel:取消当前线程,但是不能取消正在执行的线程
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
[self testThreadStatus];
}
- (void)testThreadStatus{
NSLog(@"%d %d %d", self.t.isExecuting, self.t.isFinished, self.t.isCancelled);
if ( self.t == nil || self.t.isCancelled || self.t.isFinished ) {
self.t = [[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil];
self.t.name = @"跑步线程";
[self.t start];
}else{
NSLog(@"%@ 正在执行",self.t.name);
[self.t cancel]; self.t = nil;
}
}
- (void)run{
NSLog(@"开始");
// 下面的代码的作用是判断线程状态,可能因为下面的延时,阻塞会带来当前线程的一些影响
[NSThread sleepForTimeInterval:3];
// 判断线程是否被取消
if ([NSThread currentThread].isCancelled) {
NSLog(@"%@被取消",self.t.name);
return;
}
for (NSInteger i = 0; i < 10; i++) {
// 判断线程是否被取消
if ([NSThread currentThread].isCancelled) {
NSLog(@"%@被取消",self.t.name);
return;
}
if (i == 3) {
// 睡指定的时长(秒)
[NSThread sleepForTimeInterval:1];
}
NSLog(@"%@ %zd", [NSThread currentThread], i);
// 内部取消线程 // 强制退出 - 当某一个条件满足,不希望线程继续工作,直接杀死线程,退出
if (i == 8) {
// 强制退出当前所在线程!后续的所有代码都不会执行
[NSThread exit];
}
}
NSLog(@"完成");
}