runloop理解

iOS中,提供了两个这样的对象:NSRunLoop 和 CFRunLoopRef

CFRunLoopRef是在CoreFoundation框架内的,它提供了纯C函数的API,所有这些API都是线程安全的,代码是开源的。

NSRunLoop是基于CFRunLoopRef的封装,提供了面向对象的API,但是这些API不是线程安全的。

RunLoop对外的接口

在CoreFoundation里面关于RunLoop有几个类:

  

CFRunLoop

    kCFRunLoopEntry = (1UL << 0),

    kCFRunLoopBeforeTimers = (1UL << 1),

    kCFRunLoopBeforeSources = (1UL << 2),

    kCFRunLoopBeforeWaiting = (1UL << 5),即将进行休眠

    kCFRunLoopAfterWaiting = (1UL << 6),

    kCFRunLoopExit = (1UL << 7),

    kCFRunLoopAllActivities = 0x0FFFFFFFU

CFRunLoopSourceRef是事件产生的地方。

CFRunLoopTimerRef是基于时间的触发器

CFRunLoopObserverRef是观察者,


首先添加runloop观察者,这里是用纯c语言写的

#pragma mark--1

[NSThread mainThread] 获取主线程 [NSThread currentThread] 获取当前线程

      

 //调用runloop底层设计,运行纯c代码写,可以直接拷贝到代码里用

    [self addRunloopObserver];

    //runLoop,解决拉动tableviewcell,顶部无线轮播不滚动等

    //目的:

    //1保证程序不退出

    //2负责监听所有的时间,触摸(UI界面的处理),时钟,网络事件

    //3 RunLoop 它还需要做UI的绘制,在一次tunloop循环中要绘制屏幕上有变化的所有的点

    //NSDefaultRunLoopMode--时钟网络事件

    // NSRunLoopCommonModes--用户交互(UI事件处理)

  //方法一:UI处理优先级更高

    NSTimer * timer = [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updataTimer) userInfo:nil repeats:YES];

    //加入运行循环

    [[NSRunLoop currentRunLoop]addTimer:timer forMode:NSRunLoopCommonModes];

      //方法二:时钟处理

    [NSTimer scheduledTimerWithTimeInterval:1.0 target:self selector:@selector(updataTimer) userInfo:nil repeats:YES];

    

    //注意在这里千万不要做耗时操作

   -(void)updataTimer{

      static int num = 0;

    //如果出现耗时操作。导致和ui界面优先级一样,UI会出现偶尔卡顿

    //打印当前线程

    NSLog(@"%@ %d",[NSThread currentThread],num++);

   }

   #pragma mark--2

    //解决问题:卡顿问题  分析:为什么会卡顿 一次runloop循环需要给绘制屏幕上所有的点,一次runloop需要绘制15张高清图片   

    /*思路

    1 监听Runloop循环,C语言

    2 Runloop循环一次的时候,从数组里面拿到代码执行(数组是有长度的)

    */

    //viewdidload里面添加runloop观察者方法addRunloopObserver

    //cell里面添加addTask方法

     [self addTask:^BOOL{

      //将添加图片的代码写在block里面

          return YES;      

     }];

#pragma mark --<关于runloop的方法和函数>

   //添加任务的方法

  -(void)addTask:(RunloopBack )unit{

    [self.tasks addObject:unit];

    //保证数组里面只有30个任务

    if (self.tasks.count > self.maxQueueLength) {

        [self.tasks removeObjectAtIndex:0];

    }

}


//这里是用纯c语言写runloop的底层设计,我也不知道为什么要这样写,可以直接用

-(void)addRunloopObserver{

    //获取当前Runloop

    CFRunLoopRef runloop =CFRunLoopGetCurrent();

    //定义一个上下文

    CFRunLoopObserverContext context = {

        0,

        (__bridge void*)self,

        &CFRetain,

        &CFRelease,

        NULL

        

    };

  //定义观察者  CallBack是个回调函数

    static CFRunLoopObserverRef defaultObserver ;

    //创建观察者

  defaultObserver  = CFRunLoopObserverCreate(NULLkCFRunLoopBeforeWaitingYES,NSIntegerMax-999, &CallBack, &context);

    //添加当前的runloop的观察者

    CFRunLoopAddObserver(runloop, defaultObserver, kCFRunLoopDefaultMode);

    //c语言有creat就需要release

    CFRelease(defaultObserver);


}

//runloop回调函数

//从数组里面拿代码执行

static void CallBack(CFRunLoopObserverRef observer, CFRunLoopActivity activity, void *info){

    ViewController * VC= (__bridge ViewController *)(info);

    if (VC.tasks.count ==0) {

        return;

    }

    BOOL result = NO;

    while (result ==NO && VC.tasks.count) {

        //取出任务

        RunloopBack unit= VC.tasks.firstObject;

        //执行任务

       result =  unit();

        //干掉刚执行完毕的任务

        [VC.tasks removeObjectAtIndex:0];

    }

 //   NSLog(@"来了");


}



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值