Reputation: 91
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.
Upvotes: 0
Views: 131
Reputation: 2805
You are making Network call on Main Thread that's why it is doing two things at same time
Rendering UITableView Cells
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.
Upvotes: 2