Search code examples
iosuitableviewcustom-cell

Memory growing in UITableViewCell


My code for custom cell:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"ImageView"];
    NSURL *nsurl = [NSURL URLWithString:_imageUrls[indexPath.row]];
    NSData *data = [NSData dataWithContentsOfURL: nsurl];

    cell.imageView.image = [UIImage imageWithData:data];
    if (cell == nil) {
        cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"ImageView"];
    }

    return cell;

And I have custom class VKTableViewCell:

   @interface VKTableViewCell : UITableViewCell
    @property (weak, nonatomic) IBOutlet UIImageView *image;

    @end

Image is about 800x800 (parsed from site). When I scroll my table, memory is growing (from 20 to 30mb with 100 images load). Why this happening? What I must do in this case? I am using ARC.


Solution

  • You are making Network call on Main Thread that's why it is doing two things at same time

    1. Rendering UITableView Cells

    2. Making Network call for Images

    Now You have to shift your Network call logic from Main Thread to BackGround Thread

    dispatch_queue_t callerQueue = dispatch_get_current_queue();
    dispatch_queue_t downloadQueue = dispatch_queue_create("com.myapp.processsmagequeue", NULL);
    dispatch_async(downloadQueue, ^{
        NSData * imageData = [NSData dataWithContentsOfURL:url]; //Make Network call on BackGround Thread
    
        dispatch_async(callerQueue, ^{
            // Assign Your Image to UIimageView of Cell here on Main Thread
            [cell setNeedsLayout]; // To Refresh Cell
        });
    });
    

    Also You can use a third Party Api AFNetWorking or SDWebImage

    [imageView setImageWithURL:[NSURL URLWithString:@"http://i.imgur.com/r4uwx.jpg"] placeholderImage:[UIImage imageNamed:@"placeholder-avatar"]];
    

    New Solution:

    Lazy load all the images in UITableViewCell for that just make a UIImageView extension like below

    extension UIImageView {
        func downloadImageFrom(_ link:String, contentMode: UIView.ContentMode) {
    
            guard let url = URL(string: link) else {
               return
            }
            URLSession.shared.dataTask(with: url) { [weak self] (data, response, error) in
                guard let `self` = self else { return }
                DispatchQueue.main.async {
                    self.contentMode = contentMode
                    self.image = UIImage(data: data ?? Data())
                }
            }.resume()
        }
    }
    

    Function Call:

    cell.imageView.image = UIImage(named: "placeholder")  //set placeholder image first.
    cell.imageView.downloadImageFrom(link: dataSource[indexPath.row], contentMode: UIViewContentMode.ScaleAspectFit)  //set your image from link array.