zoukankan      html  css  js  c++  java
  • iOS 如何保持线程一直在运转(二)

    一、接着上一篇通过NSThread可以方便的创建一个线程,并且启动线程的Runloop,在线程体中执行一个while循环

      然后我们就可以方便得利用这个线程了

    - (void)threadRun:(NSThread *)thread
    {
        NSLog(@"Thread run");
        NSLog(@"hello 1");
        while (!_isCancelled && [currentRunLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]])
        {
            NSLog(@"hello 2");
            _isCancelled = [currentThread isCancelled];
        }
        NSLog(@"hello 3");
    }
    

    二、那我们应该如何正确结束一个NSThread呢

      NSThread结束可以调用两个方法,一个是对象方法-[Thread cancel],这个方法标记NSThraed的属性isCanceled为YES,那么通过配合上面的循环,线程体本身就结束了。

                      另外一个方法是+[Thread exit],注意这个方法需要在NSThraed为当前线程中调用,该方法比较暴力不管线程中的任务是否还在执行,

                                      直接结束,也不管runloop,因此可能带来内存泄露。

    三、NSRunloop

      - (BOOL)runMode:(NSRunLoopMode)mode beforeDate:(NSDate *)limitDate;

      根据官方文档,上面的API在Runloop中没有事件源或者timer的时候,该方法会立即返回NO,所以在执行这个线程体的循环时候,需要先加入一个timer

      保证while循环不会结束,也就保证了线程不会结束

    - (void)threadRun:(NSThread *)thread
    {
        NSLog(@"Thread run");
    
        
        _liveTimer = [NSTimer scheduledTimerWithTimeInterval:[[NSDate distantFuture] timeIntervalSinceNow]
                                         target:self
                                       selector:@selector(ignore:)
                                       userInfo:nil
                                        repeats:YES];
         
        
        NSThread *currentThread = [NSThread currentThread];
        NSRunLoop *currentRunLoop = [NSRunLoop currentRunLoop];
        
        _isCancelled = [currentThread isCancelled];
    
        NSLog(@"hello 1");
        while (!_isCancelled && [currentRunLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]])
        {
            NSLog(@"hello 2");
            _isCancelled = [currentThread isCancelled];
            NSLog(@"hello 4");
        }
        NSLog(@"hello 3");
    
    }
    

       上面的含义另外一层意思就是,只要循环结束,线程体结束,那么NSThread也就结束,NSThread中的Runloop也结束了,而不管Runloop中的什么事件有没有执行完

     那么一旦Runloop起来之后,将Runloop中的事件全部移除之后,Runloop是否会自动结束呢

      

    - (void)stopThread:(NSThread *)thread
    {
        //[self performSelector:@selector(stopThread:) withObject:thread afterDelay:5];
        [_liveTimer invalidate];
        //CFRunLoopStop(CFRunLoopGetCurrent());
        //[thread cancel];
        //_isCancelled = YES;
        //while ([thread isExecuting] == YES) usleep(10000);
        NSLog(@"stop done");
        
    }
    
    - (void)ignore:(NSTimer *)timer
    {
        NSLog(@"ignore");
    }
    
    - (void)threadRun:(NSThread *)thread
    {
        NSLog(@"Thread run");
        
         //占用0%的CPU
        
        _liveTimer = [NSTimer scheduledTimerWithTimeInterval:[[NSDate distantFuture] timeIntervalSinceNow]
                                         target:self
                                       selector:@selector(ignore:)
                                       userInfo:nil
                                        repeats:YES];
         
        
        NSThread *currentThread = [NSThread currentThread];
        NSRunLoop *currentRunLoop = [NSRunLoop currentRunLoop];
        
        _isCancelled = [currentThread isCancelled];
    
        
        NSLog(@"hello 1");
        while (/*!_isCancelled && */[currentRunLoop runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]])
        {
            NSLog(@"hello 2");
            //_isCancelled = [currentThread isCancelled];
            NSLog(@"hello 4");
        }
        NSLog(@"hello 3");
    
    }
    

      上面的代码中去除了cancel标记,那么即使timer移除,这个while还在一直保持循环,因为- (BOOL)runMode:(NSRunLoopMode)mode beforeDate:(NSDate *)limitDate;不会返回第二次值

      那么如果没有while循环了呢,这个线程体也就真正结束啦

      

  • 相关阅读:
    Unity实现Bezier曲线的移动(三点之间的Bezier曲线的移动)
    error CS2001: Source file `Assets/Pro Standard Assets/Image Based/SaveGameData.cs' could not be found 错误
    Some objects were not cleaned up when closing the scene. (Did you spawn new GameObjects from OnDestroy?) 错误
    Unity拖拽旋转2D物体
    Unity预编译
    Activity的四种launchMode
    接入华为海外SDK支付,按下home键,之后支付页面被销毁
    Android动态权限申请
    armeabi与armeabi-v7a的区别
    win7上帝模式
  • 原文地址:https://www.cnblogs.com/doudouyoutang/p/6616656.html
Copyright © 2011-2022 走看看