zoukankan      html  css  js  c++  java
  • iOS中UITableViewCell的重用问题解决方案

    UITableViewCell重用

    • 为了能够保证tableViewCell能够高效的执行,Objective-c中引进了重用队列的机制,重影现象也是在重用队列时经常遇到的问题,那么如何解决这个问题呢?下面给出了几种解决办法。

    第一种解决方法

    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    
    {
         NSArray *subViews = cell.contentView.subviews;
    
         for (UIView *view in subViews) {
    
            [view removeFromSuperview];
        }
    }  

    以上只是列举了方法实现的位置,并没有将所有代码写出来。上面的实现方法是将cell.contentView上面的子视图全部取出来,把它们一一移除,这是解决问题的一种方法,如果子视图过多的话,每次重用的时候都会一一把子视图移除会在程序的执行效率上产生问题。

    第二种解决办法

    • 我们会这样想,既然全部移除后再一一初始化使用这种办法在执行效率上不是很高,那如果在除了第一次申请内存空间外,其它的情况下,在使用之前先判断当前子视图是否存在,如果存在的话就把上面的内容换掉不就避免了重复申请内存的问题吗
    • - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
      {
          NSDictionary *dicUserInfo = [self.statusList[indexPath.section] objectForKey:@"user"];
          NSDictionary *statusInfo = self.statusList[indexPath.section];
          NSUInteger widthSpace = 5;
          //cell的重用队列
          static NSString *cellIdentifier = @"statusCell";
          UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
          if (nil == cell) {
              cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier];
              //下面是对微博头部的定义
              UIImageView *imageView = [[UIImageView alloc] initWithFrame:CGRectMake(5, 5, 35, 35)];
              imageView.tag = 1000;
              [cell.contentView addSubview:imageView];
              UILabel *labelScreenName = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMaxX(imageView.frame)+widthSpace, 2, 100, 20)];
              labelScreenName.font = [UIFont systemFontOfSize:12.0f];
              labelScreenName.tag = 1001;
              [cell.contentView addSubview:labelScreenName];
              UILabel *labelCreateTime = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMaxX(imageView.frame)+widthSpace,CGRectGetHeight(labelScreenName.frame)+ 2,150,20)];
              labelCreateTime.font = [UIFont systemFontOfSize:12.0f];
              labelCreateTime.tag = 1002;
              [cell.contentView addSubview:labelCreateTime];
              UILabel *labelSource = [[UILabel alloc] initWithFrame:CGRectMake(CGRectGetMaxX(labelCreateTime.frame)+widthSpace, CGRectGetHeight(labelScreenName.frame)+2, 100, 20)];
              labelSource.tag = 1003;
              labelSource.font = [UIFont systemFontOfSize:12.0f];
              [cell.contentView addSubview:labelSource];
          }
          UIImageView *imgView = (UIImageView*)[cell.contentView viewWithTag:1000];
          NSURL *imgURL = [NSURL URLWithString:[dicUserInfo objectForKey:@"profile_image_url"]];
          [imgView setImageWithURL:imgURL];
          //微博用户名称
          UILabel *screenName = (UILabel*)[cell.contentView viewWithTag:1001];
          screenName.text = [dicUserInfo objectForKey:@"screen_name"];
          //微博创建时间
          UILabel *createTime = (UILabel*)[cell.contentView viewWithTag:1002];
          NSString *strDate = [statusInfo objectForKey:@"created_at"];
          NSDateFormatter *dateFormatter = [[NSDateFormatter alloc] init];
          [dateFormatter setDateFormat:@"EEE MMM dd HH:mm:ss ZZZ yyyy"];
          NSDate *dateFromString = [dateFormatter dateFromString:strDate];
          NSTimeInterval interval = [dateFromString timeIntervalSinceNow];
          createTime.text = [NSString stringWithFormat:@"%d分钟之前",abs((int)interval/60)];
          //微博来源
          UILabel *labelSource =(UILabel*)[cell.contentView viewWithTag:1003];
          NSString *xmlSourceString = [statusInfo objectForKey:@"source"];
          NSDictionary *dicSource = [NSDictionary  dictionaryWithXMLString:xmlSourceString];
          labelSource.text = [dicSource objectForKey:@"__text"];
          return cell;
      }
    • 第二种解决方法是通过微博的代码进行举例的,这个方法是通过给cell.contentView上面的所有子视图添加一个tag,因为tag是视图的唯一标识符,当使用重用队列的时候,只需要通过tag把子视图取出来,通过改变子视图上面的内容来改变显示的内容即可。这个方法的执行效率显然比第一种解决办法要高的多。

    第三种解决办法

    • 了解面向对象的人都明白,这里可以采用封装的方式,可以实现同样的作用。其实这种方法和第二种方法差不多,就是新建一个自定义的类来实现上述的功能,如自定义一个cell类,可以把上述功能封装到自定义的类中,使用自定义的类可以也可以实现,但是自定义的类中一般只对固定不变的类进行封装。大家有兴趣可以试验一下这个方法。
  • 相关阅读:
    jdk1.7下载
    Java导入导出Excel工具类ExcelUtil
    对接支付宝沙箱测试代码参数设置
    对接支付宝遇到的坑sign check fail: check Sign and Data Fail
    eclipse 如何配置activity(无网络状态下)
    Redis的总结
    java实现给pdf文件加水印!
    java中位移算法!
    spring整合springmvc案例
    读书笔记
  • 原文地址:https://www.cnblogs.com/xinianhao/p/3776219.html
Copyright © 2011-2022 走看看