美文网首页iOS Developer
运行循环在表视图中的应用

运行循环在表视图中的应用

作者: 小苗晓雪 | 来源:发表于2017-03-14 14:34 被阅读19次

    本代码仿照国外开发者写的方法TableView流畅加载高清无码大图 , 创建Runloop每次只执行一张大图!
    三张大图都是很大的桌面图:

    Batman.jpg Joker.jpg Joker1.jpg

    效果如下请看gif图:

    • 首先看一下不适用RunLoop的情况,真的是非常慢!!!


      不使用RunLoop的情况.gif
    • 再看一下RunLoop添加之后的情况 , 很流畅 ! 但是怎么老有空的?!应该是我代码没写完整.....但是思路没有错!!!


    ViewController.m文件

    #import "ViewController.h"
    //定义一个代码块封装添加图片和文字的整个一套方法:
    typedef void (^RunloopBlock) (void) ;
    static NSString *const MD_IDENTIFIER = @"MD_IDENTIFIER" ;
    static NSInteger const CELL_Height = 135.f ;
    
    @interface ViewController () <UITableViewDelegate , UITableViewDataSource>
    @property (nonatomic , strong) UITableView *MD_TableView ;
    //定义一个事件出来:
    @property (nonatomic , strong) NSTimer *timer ;
    //定义一个数组来放block代码块任务:
    @property (nonatomic , strong) NSMutableArray *taskArray ;
    //从数组中取出最后的6个cell钟的18张图片(最大任务数)(最大队列长度):
    @property (nonatomic , assign) NSInteger maxQueueLength ;
    
    @end
    
    @implementation ViewController
    
    - (void)viewDidLoad {
        [super viewDidLoad];
        self.MD_TableView = [[UITableView alloc] initWithFrame:self.view.bounds] ;
        self.MD_TableView.delegate = self ;
        self.MD_TableView.dataSource = self ;
        [self.MD_TableView registerClass:[UITableViewCell class] forCellReuseIdentifier:MD_IDENTIFIER] ;
        [self.view addSubview:self.MD_TableView] ;
        
        self.timer = [NSTimer scheduledTimerWithTimeInterval:.001 target:self selector:@selector(timerMethod) userInfo:nil repeats:YES] ;
        
        self.taskArray = [NSMutableArray array] ;
        self.maxQueueLength = 18 ;
        
        //添加Runloop的观察者方法:
        [self addRunloopObserver] ;
    }
    
    //这里面不做事情 , 目的是让Runloop循环一直跑起来!
    - (void)timerMethod {
        NSLog(@"方法名: %s , 行数: %zd" , __FUNCTION__ , __LINE__) ;
    }
    
    - (void)viewWillAppear:(BOOL)animated {
        [super viewWillAppear:animated] ;
        self.MD_TableView.frame = self.view.frame ;
    }
    
    #pragma mark - cell内部方法
    + (void)addLabelForCell:(UITableViewCell *)cell andIndexPath:(NSIndexPath *)indexPath {
        UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(5, 5, 300, 25)] ;
        label.backgroundColor = [UIColor clearColor] ;
        label.textColor = [UIColor redColor] ;
        label.text = [NSString stringWithFormat:@"%zd - Joker大图", indexPath.row] ;
        label.font = [UIFont boldSystemFontOfSize:13] ;
        label.tag = 4 ;
        [cell.contentView addSubview:label] ;
        
        UILabel *label1 = [[UILabel alloc] initWithFrame:CGRectMake(5, 99, 300, 35)];
        label1.lineBreakMode = NSLineBreakByWordWrapping ;
        label1.numberOfLines = 0 ;
        label1.backgroundColor = [UIColor clearColor] ;
        label1.textColor = [UIColor colorWithRed:0 green:100.f/255.f blue:0 alpha:1] ;
        label1.text = [NSString stringWithFormat:@"%zd - Batman大图.", indexPath.row] ;
        label1.font = [UIFont boldSystemFontOfSize:13] ;
        label1.tag = 5;
        [cell.contentView addSubview:label1] ;
    }
    
    #pragma mark - 加载第 1 张图片
    + (void)addImage1WithCell:(UITableViewCell *)cell {
        UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(5, 20, 85, 85)] ;
        imageView.tag = 1 ;
        NSString *path = [[NSBundle mainBundle] pathForResource:@"Joker" ofType:@"jpg"] ;
        UIImage *image = [UIImage imageWithContentsOfFile:path] ;
        imageView.contentMode = UIViewContentModeScaleAspectFit ;
        imageView.image = image ;
        
        [UIView transitionWithView:cell.contentView duration:.1 options:(UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionTransitionCrossDissolve) animations:^{
            [cell.contentView addSubview:imageView] ;
        } completion:nil] ;
    }
    
    #pragma mark - 加载第 2 张图片
    + (void)addImage2WithCell:(UITableViewCell *)cell {
        UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(105, 20, 85, 85)] ;
        imageView.tag = 2 ;
        NSString *path = [[NSBundle mainBundle] pathForResource:@"Batman" ofType:@"jpg"] ;
        UIImage *image = [UIImage imageWithContentsOfFile:path] ;
        imageView.contentMode = UIViewContentModeScaleAspectFit ;
        imageView.image = image ;
        
        [UIView transitionWithView:cell.contentView duration:.1 options:(UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionTransitionCrossDissolve) animations:^{
            [cell.contentView addSubview:imageView] ;
        } completion:nil] ;
    }
    
    #pragma mark - 加载第 3 张图片
    + (void)addImage3WithCell:(UITableViewCell *)cell {
        UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(205, 20, 85, 85)] ;
        imageView.tag = 3 ;
        NSString *path = [[NSBundle mainBundle] pathForResource:@"Joker1" ofType:@"jpg"] ;
        UIImage *image = [UIImage imageWithContentsOfFile:path] ;
        imageView.contentMode = UIViewContentModeScaleAspectFit ;
        imageView.image = image ;
        
        [UIView transitionWithView:cell.contentView duration:.1 options:(UIViewAnimationOptionCurveEaseInOut | UIViewAnimationOptionTransitionCrossDissolve) animations:^{
            [cell.contentView addSubview:imageView] ;
        } completion:nil] ;
    }
    
    #pragma mark - <UITableViewDataSource>
    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
        return 200 ;
    }
    
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:MD_IDENTIFIER] ;
        cell.selectionStyle = UITableViewCellSelectionStyleNone ;
        //删除cell上面已经流出的子控件 , 节约内存:
        for (NSInteger i = 1; i <= 5; i++) {
            [[cell.contentView viewWithTag:i] removeFromSuperview] ;
        }
        
        [self addTask:^{
            //添加Label:
            [ViewController addLabelForCell:cell andIndexPath:indexPath] ;
        }] ;
        [self addTask:^{
            [ViewController addImage1WithCell:cell] ;
        }] ;
        [self addTask:^{
            [ViewController addImage2WithCell:cell] ;
        }] ;
        [self addTask:^{
            [ViewController addImage3WithCell:cell] ;
        }] ;
        
        return cell ;
    }
    
    #pragma mark - <Runloop>
    //定义一个回调函数:
    static void callBack(CFRunLoopObserverRef observer , CFRunLoopActivity activity , void *info) {
        ViewController *VC = (__bridge ViewController *)(info) ;
        if (VC.taskArray.count == 0) {
            return ;
        } else {
            RunloopBlock task = VC.taskArray.firstObject ;
            //执行任务:
            task() ;
            //删除执行完毕后的任务:
            [VC.taskArray removeObjectAtIndex:0] ;
        }
    }
    
    - (void)addRunloopObserver {
        //获取当前的Runkoop:
        CFRunLoopRef runloop = CFRunLoopGetCurrent() ;
        //定义一个观察者:
        static CFRunLoopObserverRef defaultModeObserver ;
        //定义一个上下文:
        //这是一个C语言结构体:
        CFRunLoopObserverContext context = {
            0,
            (__bridge void *)self,
            &CFRetain,
            &CFRelease,
            NULL
        } ;
        //创建观察者:
        defaultModeObserver = CFRunLoopObserverCreate(NULL, kCFRunLoopBeforeWaiting, YES, 0, callBack, &context) ;
        
        //把观察者添加为Runloop的观察者:
        CFRunLoopAddObserver(runloop, defaultModeObserver, kCFRunLoopDefaultMode) ;
        //C语言需要release释放create指针:
        CFRelease(defaultModeObserver) ;
        
    }
    
    #pragma mark - 添加任务的方法
    - (void)addTask:(RunloopBlock)task {
        [self.taskArray addObject:task] ;
        if (self.taskArray.count > _maxQueueLength) {
            [self.taskArray removeObjectAtIndex:0] ;
        }
    }
    
    
    
    #pragma mark - <UITableViewDelegate>
    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath {
        return CELL_Height ;
    }
    
    
    - (void)didReceiveMemoryWarning {
        [super didReceiveMemoryWarning];
        
    }
    
    @end
    
    

    愿编程让这个世界更美好

    相关文章

      网友评论

        本文标题:运行循环在表视图中的应用

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