iOS 开启常驻线程

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里面暂时没有采用任务队列模式,都是触发式的,界面触发则一条道走到黑。其实这样是不好的,界面触发一个,你就的有一条道对应,道多不说,而且难以维护。我测试的代码 稍后上传。

代码来啦,这里

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值