iOS上开启常驻线程,有几个方式,我做了几个测试。(关于什么是常驻线程,不熟悉的同学自己脑补一下吧)
1 iOS系统支持POSIX线程模型,当然就可以使用POSIX那一套线程api来开启常驻线程。
void thread_fucn(void* arg)
{
while (1)
{
// doing work here ...
sleep(1);
}
}
2 iOS高层API NSThread,可以开启一个线程,但是,开启一个常驻线程,有几个方式
- (void)onStart:(UIButton*)sender
{
NSLog(@"start %@",self.navigationItem.title);
[NSThread detachNewThreadSelector:@selector(onThread:) toTarget:self withObject:nil];
}
- (void)onThread:(id)sneder
{
NSLog(@"run ...");
self.workerThread_NS = [NSThread currentThread];
[NSTimer scheduledTimerWithTimeInterval:1 target:self selector:@selector(onCheckNSTask:) userInfo:nil repeats:YES];
[[NSRunLoop currentRunLoop] run];
NSLog(@"over");
}
- (void)onCheckNSTask:(id)sender
{
NSLog(@"checking ..");
}
或者如下
- (void)onStart:(UIButton*)sender
{
NSLog(@"start %@",self.navigationItem.title);
[NSThread detachNewThreadSelector:@selector(onThread:) toTarget:self withObject:nil];
}
- (void)onThread:(id)sneder
{
self.workerThread_NS = [NSThread currentThread];
// Should keep the runloop from exiting
CFRunLoopSourceContext context = {0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL};
CFRunLoopSourceRef source = CFRunLoopSourceCreate(kCFAllocatorDefault, 0, &context);
CFRunLoopAddSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode);
BOOL runAlways = YES; // Introduced to cheat Static Analyzer
while (runAlways) {
CFRunLoopRun();
}
// Should never be called, but anyway
CFRunLoopRemoveSource(CFRunLoopGetCurrent(), source, kCFRunLoopDefaultMode);
CFRelease(source);
}
3 iOS底层API GCD库支持开启新的dispatch_queue_t,这个是一个线程管理器,给其不同参数,开启不同的线程模式:线性、并发模式
- (void)onStart:(UIButton*)sender
{
NSLog(@"start %@",self.navigationItem.title);
_workerqueue = dispatch_queue_create("myworkerqueue", DISPATCH_QUEUE_SERIAL);
}
static int iCnt = 0;
- (void)onAddTask:(UIButton*)sender
{
iCnt++;
{
__block int iThis = iCnt;
NSLog(@" onAddTask ...%d",iThis);
dispatch_async(self.workerqueue, ^{
//
NSLog(@"add and eat the task ...%d", iThis);
sleep(2);
NSLog(@"eat up task %d",iThis);
});
}
}
前面两种常驻线程都可以通过更改执行标志来使线程停止循环走到函数尾,结束这个线程,但是GCD的queue却没有这个。暂时不知道怎么回收这个资源,估计使用与
dispatch_queue_create对应的 xxxx release之类的吧。没有研究过。
这时候需要设计任务队列模型,对于逻辑层的各种业务就有迹可循了,一个一个执行的嘛。不管你界面怎么交互的,我的逻辑层都是一个一个执行,而且可以对任务做一些额外的统一处理:失败自动重试,日至记录等等
不过,目前我的App里面暂时没有采用任务队列模式,都是触发式的,界面触发则一条道走到黑。其实这样是不好的,界面触发一个,你就的有一条道对应,道多不说,而且难以维护。我测试的代码 稍后上传。
代码来啦,这里