多线程iOS记录iOS常用

iOS 创建常驻线程

2021-04-01  本文已影响0人  包砸豆沙馅

iOS中默认就有个主线程即mainThread,我们的UI线程指的就是主线程,一般都是在主线程中操作UI,从某个角度来讲,我们的主线程就是一个常驻线程。

一般情况下,我们开启一个子线程,让子线程去跑一个任务,当任务执行完毕之后,该线程就会被系统自动销毁。假如说 在一个遍历循环中,要执行10000次创建子线程去执行一个耗时任务,那么这么频繁的去创建和销毁线程就会造成资源的浪费,那我们为什么不让频繁使用的子线程常驻在内存中,想用的时候就用,不想用的时候让他休眠呢?

接下来就示例创建一个常驻线程。

@interface ThreadManager : NSObject
@property (nonatomic, assign, class) BOOL isShouldKeepRunning;
@end
@interface ThreadManager()
@property (nonatomic, strong, class) NSThread * residentThread;
@end

其中isShouldKeepRuning属性可以用来控制当前子线程中runloop是否停止
residentThread为要创建引用的常驻线程

static BOOL _isShouldKeepRuning;
static NSThread * _residentThread;

为其提供getter和setter方法

+ (BOOL)isShouldKeepRunning {
    return _isShouldKeepRuning;
}

+ (void)setIsShouldKeepRunning:(BOOL)isShouldKeepRunning {
    _isShouldKeepRuning = isShouldKeepRunning;
}

+ (NSThread *)residentThread {
    if (_residentThread == nil) {
        // thread方法为创建线程的方法,下面会写到。
        _residentThread = [self thread];
    }
    return _residentThread;
}

+ (void)setResidentThread:(NSThread *)residentThread {
    _residentThread = residentThread;
}

提供线程创建的方法 以及在子线程中获取runloop

+ (NSThread *)thread {
    NSThread * thread = nil;
    __weak typeof(self)weakSelf = self;
    void(^creatThreadBlock)(void) = ^{
        NSRunLoop * currentLoop = [NSRunLoop currentRunLoop];
        [currentLoop addPort:[NSPort port] forMode:NSDefaultRunLoopMode];
        while (weakSelf && weakSelf.isShouldKeepRunning) {
            [currentLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
        }
        NSLog(@"runloop 停止! ! !");
    };
    self.isShouldKeepRunning = YES;
    if (@available(iOS 10.0, *)) {
        thread = [[NSThread alloc] initWithTarget:self selector:@selector(creatThreadMethod:) object:creatThreadBlock];
    } else {
        thread = [[NSThread alloc] initWithBlock:creatThreadBlock];
    }
    thread.name = @"thread_resident";
    [thread start];
    return thread;
}

+ (void)creatThreadMethod:(void(^)(void))task {
    if (task) {
        task();
    }
}

+ (void)executeTask:(void(^)(void))task {
    [self performSelector:@selector(threadTaskMethod:) onThread:self.residentThread withObject:task waitUntilDone:NO];
}

+ (void)threadTaskMethod:(void(^)(void))task {
    if (task) {
        NSLog(@"currentThread: %@", [NSThread currentThread]);
        task();
    }
}

其中

NSRunLoop * currentLoop = [NSRunLoop currentRunLoop];
[currentLoop addPort:[NSPort port] forMode:NSDefaultRunLoopMode];
 [ThreadManager executeTask:^{
        NSLog(@"1 1 1 子线程 执行操作 ");
    }];
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [ThreadManager executeTask:^{
            NSLog(@"2 2 2 子线程 执行操作 ");
        }];
    });
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(4.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [ThreadManager executeTask:^{
            NSLog(@"3 3 3 子线程 执行操作 ");
        }];
    });
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(6.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        ThreadManager.isShouldKeepRunning = NO;
    });
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(8.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [ThreadManager executeTask:^{
            NSLog(@"4 4 4 子线程 执行操作 ");
        }];
    });

结果如下:


常驻线程执行
上一篇下一篇

猜你喜欢

热点阅读