標籤:c style class blog code java
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類,可以把上述功能封裝到自訂的類中,使用自訂的類可以也可以實現,但是自訂的類中一般只對固定不變的類進行封裝。大家有興趣可以實驗一下這個方法。