美文网首页
ios- runloop

ios- runloop

作者: child_cool | 来源:发表于2017-04-23 14:14 被阅读6次
    /**
     @param argc 参数长度
     @param argv 参数值
     */
    int main(int argc, char * argv[]) {
    }
    
    /*
     runloop - 运行循环
     1.保证程序不退出,也就是建立死循环
     2.负责监听事件(网络事件,时钟事件,触摸事件)
     3.如果没有事件发生,runloop进入休眠状态
    4.渲染图片,在一次循环中渲染所有的图片
     
     每一条线程上都会有一个runloop。但是默认不开启,想让线程不被释放,需要将该线程的runloop运行起来
     屏幕每秒钟闪烁60次
     
     模式:
     默认模式-NSDefaultRunLoopMode 
     ui处理模式-UITrackingRunLoopMode(优先级高)(只能被ui事件触发)  
     占位模式 - NSRunLoopCommonModes  可以解决时钟事件和ui处理事件的冲突(有隐患)
     模式上的事件:source timer observe
     /*
     source  : 事件源  
            source0:非内核事件
            source1:系统内核事件
     observe : 观察者
     timer : 时钟
     */
     如果在时钟监听事件中执行耗时操作(线程睡眠,)会导致主线程被阻塞
     线程归属cpu进行调度
     */
    
    解决方案一:
    使用占位模式解决事件冲突问题(如果在时钟监听事件中执行耗时操作(线程睡眠,)会导致主线程被阻塞)
    - (void)viewDidLoad {
        [super viewDidLoad];
    
        
       NSTimer *timer = [NSTimer timerWithTimeInterval:1.f target:self selector:@selector(timerMethod) userInfo:nil repeats:YES];
         [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSRunLoopCommonModes];// 添加到占位模式中
        
    }
    
    - (void)timerMethod {
        static int num = 0;
        num ++;
        NSLog(@"%@,%d",[NSThread currentThread],num);
    }
    
    
    解决方案二:
    对方案隐患的问题解决和优化
    在子线程中执行时钟会出现子线程开辟使用结束会自动释放,使用开启子线程runloop的模式解决该问题,在需要时在对子线程进行关闭或者停止runloop的运行循环
    // 1.以关闭子线程runloop的方式解决
    - (void)viewDidLoad {
        [super viewDidLoad];
        NSThread *thread = [[NSThread alloc] initWithBlock:^{
            NSTimer *timer = [NSTimer timerWithTimeInterval:1.f target:self selector:@selector(timerMethod) userInfo:nil repeats:YES];
            [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];// 添加到占位模式中
    //        [[NSRunLoop currentRunLoop] run]; // 开启子线程runloop循环
            
            while (!self.isFanished) {
                // 每次RunLoop运行的时间
                [[NSRunLoop currentRunLoop] runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.001]];
            }
        }];
        
        [thread start];
        
    }
    
    - (void)timerMethod {
        [NSThread sleepForTimeInterval:1.f]; // 模拟主线程阻塞
        static int num = 0;
        num ++;
        NSLog(@"%@,%d",[NSThread currentThread],num);
    }
    
    // 2.以杀掉子线程的方式解决
    - (void)viewDidLoad {
        [super viewDidLoad];
        NSThread *thread = [[NSThread alloc] initWithBlock:^{
            NSTimer *timer = [NSTimer timerWithTimeInterval:1.f target:self selector:@selector(timerMethod) userInfo:nil repeats:YES];
            [[NSRunLoop currentRunLoop] addTimer:timer forMode:NSDefaultRunLoopMode];// 添加到占位模式中
            [[NSRunLoop currentRunLoop] run]; // 开启子线程runloop循环
        }];
        
        [thread start];
        
    }
    
    - (void)timerMethod {
        
        if (self.isFanished) {
            [NSThread exit]; // 杀掉当前线程
        }
        
        [NSThread sleepForTimeInterval:1.f]; // 模拟主线程阻塞
        static int num = 0;
        num ++;
        NSLog(@"%@,%d",[NSThread currentThread],num);
    }
    
    - (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
        self.isFanished = YES;
    }
    
    
    小知识:
     [NSThread exit]; // 杀掉当前线程
    可以通过该方法杀掉主线程,程序不会崩溃,但ui不会再进行处理
    
    解决方案三:
    使用gcd 不需要去额外处理runloop的问题
      /**
         全局队列
    
         @param 0 优先级
         @param 0 预留参数
         */
        dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
        
        
        /**
         创建定时器
    
         @param DISPATCH_SOURCE_TYPE_TIMER 定时器类型
         @param queue 全局队列可以进行异步处理
         */
        dispatch_source_t timer = dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
        
        /**
         DISPATCH_TIME_NOW 启动时间
         1 * NSEC_PER_SEC = 1000,000,000 间隔时间 1秒
         */
        dispatch_source_set_timer(timer, DISPATCH_TIME_NOW, 1 * NSEC_PER_SEC, 0 * NSEC_PER_SEC);
        dispatch_source_set_event_handler(timer, ^{
            NSLog(@"%@",[NSThread currentThread]);
        });
        // 启动定时器
        dispatch_resume(timer);
    
    在TableViewcell中添加多张高清大图,一次性加载多个时会出现卡顿现象,示例如下:https://github.com/feng562925462/iOSRunloop-
    

    相关文章

      网友评论

          本文标题:ios- runloop

          本文链接:https://www.haomeiwen.com/subject/jwoezttx.html