寫在前面
本文主要講一下線程保活是什么赖舟、線程北鲎ィ活的意義裕偿、如何實(shí)現(xiàn)線程蓖吹ィ活旭绒。
線程保活
線程生命周期
1.png
【新建】:創(chuàng)建一個(gè)線程對(duì)象重父。
【就緒】:線程調(diào)用
start
方法忽匈,將線程加入可調(diào)度線程池中丹允,等著CPU的調(diào)度。【運(yùn)行】:CPU調(diào)度當(dāng)前線程執(zhí)行折柠。
【阻塞】:當(dāng)滿足某個(gè)預(yù)設(shè)的條件時(shí)(比如休眠或者同步鎖)會(huì)阻塞線程執(zhí)行批狐,重新將線程設(shè)置為【就緒】狀態(tài)嚣艇。
【死亡】:線程任務(wù)執(zhí)行完畢或強(qiáng)制退出,線程生命周期結(jié)束巷懈。
什么是線程被藕椋活
線程贝毡#活:一般情況下,當(dāng)線程執(zhí)行玩一次任務(wù)之后需要進(jìn)行資源回收也就意味著生命周期結(jié)束频伤,線程敝ゴ耍活就是保證線程的生命周期不結(jié)束。
線程卑陡活的應(yīng)用場(chǎng)景
當(dāng)一個(gè)任務(wù)隨時(shí)都有可能去執(zhí)行它怎炊,那么這個(gè)任務(wù)應(yīng)該放在子線程去執(zhí)行,并且讓子線程一直存活债查,避免頻繁創(chuàng)建線程而造成的性能損耗瓜挽。
大家如果看過AFNetworking的源碼就會(huì)看到框架里面是有用到線程本贸龋活的。
如何實(shí)現(xiàn)線程卑溃活
// WWPermenantThread 類
@interface WWPermenantThread : NSObject
/**
關(guān)閉線程
*/
- (void)stop;
/// 在钡叻牛活的線程里面執(zhí)行的任務(wù)
/// @param target 目標(biāo)對(duì)象
/// @param action selector
/// @param object object
- (void)excuteTaskWithTarget:(id)target action:(SEL)action object:(id)object;
/// 在保活的線程里執(zhí)行任務(wù)
/// @param task 執(zhí)行的任務(wù)
- (void)excuteTask:(void(^)(void))task;
@end
@interface WWPermenantThread ()
@property (nonatomic, strong) NSThread *innerThread;
@property (nonatomic, assign) BOOL isStopped;
@end
@implementation WWPermenantThread
- (void)dealloc {
NSLog(@"%s",__func__);
[self stop];
}
- (instancetype)init {
if (self = [super init]) {
self.isStopped = NO;
__weak typeof(self) weakSelf = self;
self.innerThread = [[NSThread alloc] initWithBlock:^{
// 添加Port到RunLoop
[[NSRunLoop currentRunLoop] addPort:[[NSPort alloc] init] forMode:NSDefaultRunLoopMode];
while (weakSelf && !weakSelf.isStopped) {
// 開啟RunLoop
[[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
}
}];
[self.innerThread start];
}
return self;
}
- (void)run {
if (!self.innerThread) {
return;
}
[self.innerThread start];
}
- (void)stop {
if (!self.innerThread) {
return;
}
[self performSelector:@selector(__stop) onThread:self.innerThread withObject:nil waitUntilDone:YES];
}
- (void)__stop {
self.isStopped = YES;
// 退出當(dāng)前RunLoop
CFRunLoopStop(CFRunLoopGetCurrent());
self.innerThread = nil;
}
- (void)excuteTaskWithTarget:(id)target action:(SEL)action object:(id)object {
if (!self.innerThread) {
return;
}
[self performSelector:action onThread:self.innerThread withObject:object waitUntilDone:NO ];
}
- (void)excuteTask:(void (^)(void))task {
if (!self.innerThread || !task) {
return;
}
[self performSelector:@selector(__excuteTask:) onThread:self.innerThread withObject:task waitUntilDone:NO ];
}
- (void)__excuteTask:(void(^)(void))task {
task();
}
@end
如何使用線程笨愿遥活
- (void)viewDidLoad {
[super viewDidLoad];
// 創(chuàng)建一個(gè)線程對(duì)象
self.thread = [[WWPermenantThread alloc] init];
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
[self.thread excuteTask:^{
NSLog(@"執(zhí)行任務(wù) - %@", [NSThread currentThread]);
}];
}
執(zhí)行結(jié)果:
2023-02-15 10:18:56.211402+0800 線程迸鲂祝活Demo1[10526:21512893] 執(zhí)行任務(wù) - <NSThread: 0x600002e99680>{number = 9, name = (null)}
2023-02-15 10:18:56.830085+0800 線程保活Demo1[10526:21512893] 執(zhí)行任務(wù) - <NSThread: 0x600002e99680>{number = 9, name = (null)}
2023-02-15 10:18:57.279150+0800 線程甭雇眨活Demo1[10526:21512893] 執(zhí)行任務(wù) - <NSThread: 0x600002e99680>{number = 9, name = (null)}
2023-02-15 10:18:58.212741+0800 線程庇停活Demo1[10526:21512893] 執(zhí)行任務(wù) - <NSThread: 0x600002e99680>{number = 9, name = (null)}
2023-02-15 10:19:32.672529+0800 線程保活Demo1[10526:21512038] -[OneViewController dealloc]
2023-02-15 10:19:32.672800+0800 線程毙笪活Demo1[10526:21512038] -[WWPermenantThread dealloc]
寫在最后
關(guān)于如何實(shí)現(xiàn)線程崩常活的筆記就記錄到這里了凄鼻,如有錯(cuò)誤請(qǐng)多多指教腊瑟,最后歡迎去我的個(gè)人技術(shù)博客逛逛。