美文网首页
Runloop实现加载大图

Runloop实现加载大图

作者: TimMei3345 | 来源:发表于2018-03-18 12:27 被阅读0次

什么是Runloop
Runloop是一个循环,用来监听事件,时钟事件、网络事件、用户交互事件

 NSDefaultRunLoopMode;  **监听时钟事件、网络事件
 NSRunLoopCommonModes;  **用户交互事件

Runloop通知监听的几种状态

    kCFRunLoopEntry = (1UL << 0),
    kCFRunLoopBeforeTimers = (1UL << 1),
    kCFRunLoopBeforeSources = (1UL << 2),
    kCFRunLoopBeforeWaiting = (1UL << 5),
    kCFRunLoopAfterWaiting = (1UL << 6),
    kCFRunLoopExit = (1UL << 7),
    kCFRunLoopAllActivities = 0x0FFFFFFFU

Runloop如何实现加载高清大图

动态数组添加任务,以前要执行的代码(加载大图),变成任务(代码块)

//MARK: 添加任务
-(void)addTask:(RunloopBlock)unit withKey:(id)key{
    [self.tasks addObject:unit];
    [self.tasksKeys addObject:key];
    //保证之前没有显示出来的任务,不再浪费时间加载
    if (self.tasks.count > self.max) {
        [self.tasks removeObjectAtIndex:0];
        [self.tasksKeys removeObjectAtIndex:0];
    }
    
}

C语言,添加一个Runloop的监听者(此时的监听者,可以是tableview的trackModel,也可以是时钟defaultModel)

//这里面都是C语言 -- 添加一个监听者
-(void)addRunloopObserver{
    //获取当前的RunLoop
    CFRunLoopRef runloop = CFRunLoopGetCurrent();
    //定义一个centext
    CFRunLoopObserverContext context = {
        0,
        ( __bridge void *)(self),
        &CFRetain,
        &CFRelease,
        NULL
    };
    //定义一个观察者
    static CFRunLoopObserverRef defaultModeObsever;
    //创建观察者
    defaultModeObsever = CFRunLoopObserverCreate(NULL,
                                                 kCFRunLoopBeforeWaiting,
                                                 YES,
                                                 NSIntegerMax - 999,
                                                 &Callback,
                                                 &context
                                                 );
    
    //添加当前RunLoop的观察者
    CFRunLoopAddObserver(runloop, defaultModeObsever, kCFRunLoopDefaultMode);
    //c语言有creat 就需要release
    CFRelease(defaultModeObsever);
   
}

实现Runloop监听者的回调方法(以至于一次回调执行一个任务)

//定义一个回调函数  一次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) {
        //取出任务
        RunloopBlock unit = vc.tasks.firstObject;
        //执行任务
        result = unit();
        //干掉第一个任务
        [vc.tasks removeObjectAtIndex:0];
        //干掉标示
        [vc.tasksKeys removeObjectAtIndex:0];
    }
    
}

执行的代码,在Block里面执行

//不要直接加载图片!! 你将加载图片的代码!都给RunLoop!!
    [self addTask:^BOOL{
        [ViewController addImage1With:cell];
        return YES;
    } withKey:indexPath];
    [self addTask:^BOOL{
        [ViewController addImage2With:cell];
        return YES;
    } withKey:indexPath];
    [self addTask:^BOOL{
        [ViewController addImage3With:cell];
        return YES;
    } withKey:indexPath];

相关文章

网友评论

      本文标题:Runloop实现加载大图

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