在Java(Android)开发中,Thread调用了sleep后,interrupt能够使sleep中的Thread马上唤醒,但iOS中并未找到直接支持Thread休眠中唤醒的方式。
iOS对于多线程的支持有NSThread、NSOperation、GCD。找了很多资料,都未找到比较好的休眠方式。故自己使用NSCondition实现了一个。
希望能够给大家带来一些帮助。如果大家有什么更好的方式,也欢迎回复讨论。
废话不多说,直接上代码:
ESPThread.h:
#import <Foundation/Foundation.h>
@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
- (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
注意:提供的代码中,借用了Java中sleep和interrupt概念,故sleep中的单位为ms。传入值为long long。不喜欢的可以根据自己的喜好来更改。