iOS线程休眠及取消

在Java(Android)开发中,Thread调用了sleep后,interrupt能够使sleep中的Thread马上唤醒,但iOS中并未找到直接支持Thread休眠中唤醒的方式。


iOS对于多线程的支持有NSThread、NSOperation、GCD。找了很多资料,都未找到比较好的休眠方式。故自己使用NSCondition实现了一个。

希望能够给大家带来一些帮助。如果大家有什么更好的方式,也欢迎回复讨论。


废话不多说,直接上代码:

ESPThread.h:

#import 

@interface ESPThread : NSObject

+ (ESPThread *) currentThread;

- (BOOL) sleep: (long long) milliseconds;

- (void) interrupt;

- (BOOL) isInterrupt;

@end

ESPThread.m:

#import "ESPThread.h"

@interface ESPThread()

@property(atomic, assign, getter=isInterrupt) BOOL isInterrupt;
@property(atomic, strong) NSCondition *condition;

@end

@implementation ESPThread

+ (ESPThread *) currentThread
{
    return [[ESPThread alloc]init];
}

- (id) init
{
    self = [super init];
    if (self)
    {
        self.isInterrupt = NO;
        self.condition = [[NSCondition alloc]init];
    }
    return self;
}

- (BOOL) sleep: (long long) milliseconds
{
    [self.condition lock];
    NSDate *date = [NSDate dateWithTimeIntervalSinceNow: milliseconds/1000.0];
    BOOL signaled = NO;
    while (!self.isInterrupt && (signaled = [self.condition waitUntilDate:date]))
    {
    }
    [self.condition unlock];
    return self.isInterrupt;
}

- (void) interrupt
{
    [self.condition lock];
    self.isInterrupt = YES;
    [self.condition signal];
    [self.condition unlock];
}

@end


使用Demo:

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.
    
    __block ESPThread *thread = [ESPThread currentThread];
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // 休眠1s后interrupt
        [thread sleep:1000];
        NSLog(@"interrupt");
        [thread interrupt];
    });
    NSLog(@"Sleep start");
    // 休眠3s
    [thread sleep:3000];
    NSLog(@"Sleep stop");
}

输出结果:

2015-09-16 13:11:15.236 XXXXXX[10213:405212] Sleep start

2015-09-16 13:11:16.237 XXXXXX[10213:405315] interrupt

2015-09-16 13:11:16.237 XXXXXX[10213:405212] Sleep stop


NSThread的Demo:

- (void)viewDidLoad
{
    [super viewDidLoad];
	// Do any additional setup after loading the view, typically from a nib.
    
    __block NSThread *thread = [NSThread currentThread];
    
    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
        // 休眠1s后cancel
        [NSThread sleepForTimeInterval:1.0];
        NSLog(@"cancel");
        [thread cancel];
    });
    NSLog(@"Sleep start");
    // 休眠3s
    [NSThread sleepForTimeInterval:3.0];
    NSLog(@"Sleep stop");
    
}

输出结果:

2015-09-16 13:15:54.585 XXXXXX[10285:408139] Sleep start

2015-09-16 13:15:55.586 XXXXXX[10285:408243] cancel

2015-09-16 13:15:57.591 XXXXXX[10285:408139] Sleep stop



可以看到,NSThread进入sleep之后,cancel是无法把Thread唤醒的。

注意:提供的代码中,借用了Java中sleep和interrupt概念,故sleep中的单位为ms。传入值为long long。不喜欢的可以根据自己的喜好来更改。

你可能感兴趣的:(IOS)