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类,可以把上述功能封装到自定义的类中,使用自定义的类可以也可以实现,但是 自定义的类中一般只对固定不变的类进行封装 。大家有兴趣可以试验一下这个方法。
时间: 2024-11-10 01:06:52