2013-11-22 35 views
0

我在xcode中有一個tableview,當前從parse.com後端下載並顯示到表中。它會下載一個小圖像並將圖像渲染成一個圓形以及每行的樣式。目前它下載大約5行並輸出可愛,但只要我上下滾動幾次tableview和應用程序變得緩慢。TableView在滾動上下幾次後變慢了

做一些研究,我可以看到建議,以添加數據提取另一個線程。目前,我對這一切都很陌生,我想知道是否有人可以幫助向我展示它是如何完成的。

我的cellForRowAtIndexPath看起來是這樣的:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
static NSString *CellIdentifier = @"Cell"; 
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 

tableView.separatorColor = [UIColor colorWithRed:192.0/255.0 green:196.0/255.0 blue:202.0/255.0 alpha:1]; 

if ([self.tableView respondsToSelector:@selector(setSeparatorInset:)]) { 
    [self.tableView setSeparatorInset:UIEdgeInsetsZero]; 
} 


if (cell == nil) 
{ 
    cell = [[UITableViewCell alloc] 
      initWithStyle:UITableViewCellStyleDefault 
      reuseIdentifier:CellIdentifier]; 
} 



PFObject *games = [self.games objectAtIndex:indexPath.row]; 

//PFFile *imageFile = [games objectForKey:@"gameCover"]; 


NSString *gameName = [games objectForKey:@"name"]; 
NSArray *gamePlatforms = [games objectForKey:@"platform"]; 

NSString *platformsResult = [gamePlatforms componentsJoinedByString:@""]; 



NSDate *rDate = [games objectForKey:@"release_date"]; 



// Check to see if the date is set to a Quarter instead 
if (rDate == (id)[NSNull null]) { 

    self.releaseDate = @"Q1/2014"; 

} else { 

    // Date on the right added to a subview 

    //Setup date 

    NSDateFormatter *formatter = [[NSDateFormatter alloc] init]; 
    //uncomment to get the time only 
    //[formatter setDateFormat:@"hh:mm a"]; 
    [formatter setDateFormat:@"dd"]; 
    //[formatter setDateStyle:NSDateFormatterLongStyle]; 


    //get the date today 


    NSDate *start = [NSDate date]; 

    NSDateFormatter *f = [[NSDateFormatter alloc] init]; 
    [f setDateFormat:@"YYYY-MM-dd"]; 

    NSCalendar *gregorianCalendar = [[NSCalendar alloc] initWithCalendarIdentifier:NSGregorianCalendar]; 
    NSDateComponents *components = [gregorianCalendar components:NSDayCalendarUnit 
                 fromDate:start 
                  toDate:rDate 
                 options:0]; 

    //NSLog(@"%ld", (long)[components day]); 

    NSInteger value = [components day]; 


    NSString *myString = [NSString stringWithFormat:@"%0.0f days", (float)value]; 


    if ([myString isEqual: @"1 days"]) 
    { 
     myString = @"1 day"; 
    } 

    self.releaseDate = myString; 


} 





// Cell Style 
// Background Color 

UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(10, 15, 300.0, 100.0)]; 
imageView.userInteractionEnabled = NO; 
imageView.backgroundColor = [UIColor colorWithRed:209.0/255.0 green:230.0/255.0 blue:244.0/255.0 alpha:1]; 

// Icon Image 



//Game Title Label 
UILabel *titleLabel = [[UILabel alloc]initWithFrame:CGRectMake(80, 25, 200, 20)]; 
titleLabel.text = gameName; 
titleLabel.backgroundColor = [UIColor clearColor]; 
titleLabel.font = [UIFont fontWithName:@"ProximaNova-Light" size:13]; 
titleLabel.textColor = [UIColor colorWithRed:44.0/255.0 green:127.0/255.0 blue:178.0/255.0 alpha:1]; 

// Game Date Label 

UILabel *dateLabel = [[UILabel alloc]initWithFrame:CGRectMake(250, 80, 50, 20)]; 
dateLabel.text = self.releaseDate; 
dateLabel.backgroundColor = [UIColor clearColor]; 
dateLabel.font = [UIFont fontWithName:@"ProximaNova-Light" size:13]; 
dateLabel.textColor = [UIColor colorWithRed:44.0/255.0 green:127.0/255.0 blue:178.0/255.0 alpha:1]; 
dateLabel.textAlignment = NSTextAlignmentRight; 

// Game Platforms 

UILabel *platformLabel = [[UILabel alloc]initWithFrame:CGRectMake(250, 25, 50, 20)]; 
platformLabel.text = platformsResult; 
platformLabel.backgroundColor = [UIColor clearColor]; 
platformLabel.font = [UIFont fontWithName:@"ProximaNova-Light" size:13]; 
platformLabel.textColor = [UIColor colorWithRed:44.0/255.0 green:127.0/255.0 blue:178.0/255.0 alpha:1]; 
platformLabel.textAlignment = NSTextAlignmentRight; 

// add the styles to the subview 

[cell addSubview:imageView]; 
//[cell addSubview:iconView]; 
[cell addSubview:titleLabel]; 
[cell addSubview:dateLabel]; 
[cell addSubview:platformLabel]; 

PFFile *imageFile = [games objectForKey:@"gameCover"]; 

// If no image 

if (imageFile != NULL) { 
    NSURL *imageFileUrl = [[NSURL alloc] initWithString:imageFile.url]; 
    NSData *imageData = [NSData dataWithContentsOfURL:imageFileUrl]; 
    UIImage *myImage = [UIImage imageWithData:imageData]; 

    UIImageView *iconView = [[UIImageView alloc] initWithImage:myImage]; 
    iconView.frame = CGRectMake(20.0, 25.0, 50.0, 50.0); 

    iconView.layer.masksToBounds = YES; 
    iconView.layer.cornerRadius = 25.0f; 

    [cell addSubview:iconView]; 
} else { 

    UIImageView *iconView = [[UIImageView alloc]initWithFrame:CGRectMake(20.0, 25.0, 50.0, 50.0)]; 
    iconView.userInteractionEnabled = NO; 
    iconView.image = [UIImage imageNamed:@"img.png"]; 

    iconView.layer.masksToBounds = YES; 
    iconView.layer.cornerRadius = 25.0f; 

    [cell addSubview:iconView]; 
} 

return cell; 
} 

很抱歉的混亂,我可以發佈更多的代碼,如果有人想它。

感謝

+2

您正在同步下載主線程上的圖像,這是原因。推薦的方法來處理這是[延遲加載'UITableView'中的圖像](http://stackoverflow.com/questions/1130089/lazy-load-images-in-uitableview)。 – Amar

+0

你創建了什麼樣的項目? ARC還是不? – alinoz

+1

是的,你需要在另一個線程中獲取,但是你的標題是「TableView在幾次上下滾動後放慢速度」,這是由於在你的單元中堆疊了你的視圖,所以這是U必須解決的另一個問題,以及異步下載 – AntonijoDev

回答

1

嗯,UR不斷增加對UITableViewCell的看法:

[cell addSubview:imageView]; 
//[cell addSubview:iconView]; 
[cell addSubview:titleLabel]; 
[cell addSubview:dateLabel]; 
[cell addSubview:platformLabel]; 

ü應該在如果(細胞==零)阻止引起他們r可重複使用的單元格添加他們只有一次..

做這樣的:

if (cell == nil) 
{ 
    cell = [[UITableViewCell alloc] 
      initWithStyle:UITableViewCellStyleDefault 
      reuseIdentifier:CellIdentifier]; 


// Cell Style 
// Background Color 

UIImageView *imageView = [[UIImageView alloc]initWithFrame:CGRectMake(10, 15, 300.0, 100.0)]; 

[imageView setTag:100]; 
imageView.userInteractionEnabled = NO; 
imageView.backgroundColor = [UIColor colorWithRed:209.0/255.0 green:230.0/255.0 blue:244.0/255.0 alpha:1]; 

//Game Title Label 
UILabel *titleLabel = [[UILabel alloc]initWithFrame:CGRectMake(80, 25, 200, 20)]; 
[titleLabel setTag:101]; 
titleLabel.backgroundColor = [UIColor clearColor]; 
titleLabel.font = [UIFont fontWithName:@"ProximaNova-Light" size:13]; 
titleLabel.textColor = [UIColor colorWithRed:44.0/255.0 green:127.0/255.0 blue:178.0/255.0 alpha:1]; 

// Game Date Label 

UILabel *dateLabel = [[UILabel alloc]initWithFrame:CGRectMake(250, 80, 50, 20)]; 
[dateLabel setTag:102]; 
dateLabel.backgroundColor = [UIColor clearColor]; 
dateLabel.font = [UIFont fontWithName:@"ProximaNova-Light" size:13]; 
dateLabel.textColor = [UIColor colorWithRed:44.0/255.0 green:127.0/255.0 blue:178.0/255.0 alpha:1]; 
dateLabel.textAlignment = NSTextAlignmentRight; 

// Game Platforms 

UILabel *platformLabel = [[UILabel alloc]initWithFrame:CGRectMake(250, 25, 50, 20)]; 
[platformLabel setTag:103]; 
platformLabel.text = platformsResult; 
platformLabel.backgroundColor = [UIColor clearColor]; 
platformLabel.font = [UIFont fontWithName:@"ProximaNova-Light" size:13]; 
platformLabel.textColor = [UIColor colorWithRed:44.0/255.0 green:127.0/255.0 blue:178.0/255.0 alpha:1]; 
platformLabel.textAlignment = NSTextAlignmentRight; 

// add the styles to the subview 

[cell addSubview:imageView]; 
//[cell addSubview:iconView]; 
[cell addSubview:titleLabel]; 
[cell addSubview:dateLabel]; 
[cell addSubview:platformLabel]; 

...... 
} 

UILabel *lbl = [cell viewWithTag:101]; 
lbl.text = gameName; 

lbl = [cell viewWithTag:102]; 
lbl.text = self.releaseDate; 

lbl = [cell viewWithTag:103]; 
lbl.text = platformsResult; 

做同樣的事情你ImageViews和U會進入可重用性和快速的表:)

的世界,也û不要下載這樣的圖片,U應該使用像別人一些異步方法recomended

+0

感謝您的幫助,我將從此開始,然後轉到加載到新線程位的圖像上。當我嘗試使用你的代碼時,我得到這部分的錯誤: UILabel * lbl = [cell viewWithTag:101];它的意思是:「不兼容的指針類型初始化'UILabel *'與一個'UIView *'類型的表達式'' – tutchmedia

+0

U意味着警告?就像這樣:UILabel * lbl =(UILabel *)[cell viewWithTag:101]; – AntonijoDev

+0

Yes ,對不起,我的意思是一個警告。改變它到你說的和運行的應用程序,什麼都沒有顯示:(任何想法? – tutchmedia

1

,因爲你在cellForRowAtIndexPath下載圖像。您必須不得不異步下載圖像。由於這種應用程序的性能會提高。所以嘗試異步下載。

0

使用此代碼異步下載你的形象在你的cellForRowAtIndexPath

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul); 
     dispatch_async(queue, ^(void) { 

      NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:parsedData[@"imageLR"]]; 

      UIImage* image = [[UIImage alloc] initWithData:imageData]; 
      if (image) { 
       dispatch_async(dispatch_get_main_queue(), ^{ 
        if (cell.tag == indexPath.row) { 
         cell.imageView.image = image; 
         [cell setNeedsLayout]; 
        } 
       }); 
      } 
     }); 
+0

這是行不通的,因爲您無法在完成處理程序中設置單元格的圖像:當單元被分派時,單元被捕獲。當完成處理程序將最終執行時,單元與相應的索引「不同步」,因爲它在此期間已被重新使用。它也沒有解決其他重要問題,例如對同一個URL調用多個請求。 – CouchDeveloper

0

替換代碼,如果這個
沒有圖像//如果沒有圖像

if (imageFile != NULL) { 
    NSURL *imageFileUrl = [[NSURL alloc] initWithString:imageFile.url]; 
dispatch_queue_t callerQueue = dispatch_get_current_queue(); 
dispatch_queue_t downloadQueue = dispatch_queue_create("Image Downloader", NULL); 
dispatch_async(downloadQueue, ^{ 
    NSData *imageData = [NSData dataWithContentsOfURL:imageFileUrl]; 
    dispatch_async(callerQueue, ^{ 
     UIImage *myImage = [UIImage imageWithData:imageData]; 

    UIImageView *iconView = [[UIImageView alloc] initWithImage:myImage]; 
    iconView.frame = CGRectMake(20.0, 25.0, 50.0, 50.0); 

    iconView.layer.masksToBounds = YES; 
    iconView.layer.cornerRadius = 25.0f; 

    [cell addSubview:iconView]; 
    }); 
}); 
} 
+0

儘管解決問題之一的「方向」是正確的,但它還是引入了一些內容:1.不要使用dispatch_get_current_queue(這個API由於某種原因而被棄用); 2.單元格將「不同步」與完成處理程序最終執行時的圖像 – CouchDeveloper

0

用戶SDWebImageCache

圖像是由這個類下載和圖像緩存在這個類的句柄,並且您的表將滾動順暢跟隨此鏈接Here