2
(void)bilgileriYukle
{
    NSMutableArray *yemekIsimleri = [[NSMutableArray alloc] init];
    NSMutableArray *resimIsimleri = [[NSMutableArray alloc] init];


    NSURL *myURL = [[NSURL alloc]initWithString:@"http://www.sevgilezzeti.com/WebServices/tarifler.php"];
    NSData *myData = [[NSData alloc]initWithContentsOfURL:myURL];
    if (myData == nil)
    {
        NSLog(@"INTERNET YOK YADA VERI CEKEMEDI");
    }
    else
    {
        NSLog(@"INTERNET VAR VERI CEKILDI");
        NSArray *jsonArray = [NSJSONSerialization JSONObjectWithData:myData options:kNilOptions error:nil];
        for (id element in jsonArray)
        {
            NSString *durum = [element objectForKey:@"durum"];
            if([durum isEqualToString:@"1"])
            {
                [yemekIsimleri addObject:[element objectForKey:@"yemekadi"]];
                NSString *gelenYemekAdi =[element objectForKey:@"kapakresmi"];
                NSString *imagePathKapak = @"http://sevgilezzeti.com/Admin/yemekresimkapak/";
                combined = [NSString stringWithFormat:@"%@%@", imagePathKapak, gelenYemekAdi];
                [resimIsimleri addObject:combined];

            }

        }

    }

    _TarifAdi=yemekIsimleri;
    _ResimAdi=resimIsimleri;

}

///////////////////////////////////////////////////////////////////////////////////////

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

    TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"TableViewCell" forIndexPath:indexPath];

       NSUInteger row = [indexPath row];

    cell.TitleLabel.text = _TarifAdi[row];


    NSCache *_imageCache;
    UIImage *image = [_imageCache objectForKey:@"DenemeRes"];
    if (image == nil) {
        NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:_ResimAdi[row]]];
        image = [UIImage imageWithData:data];
        [_imageCache setObject:image forKey:@"DenemeRes"];
    }


    cell.ThumbImage.image = image;

    return cell;

}

I can get images from URL and can see images but when I scroll the table view, it's very slow and lagging. How can I fix this problem ?

Neeku
  • 3,646
  • 8
  • 33
  • 43
mrtcnkryln
  • 324
  • 2
  • 15
  • 1
    "NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:_ResimAdi[row]]];" line is taking time. You can use GCD to make it smooth – Yogendra Jul 10 '14 at 14:11
  • I can't see `bilgileriYukle` ever being called in the code you have provided and I don't know what it's supposed to do. English names for methods and variables would help others understand your code. – David Rönnqvist Jul 10 '14 at 14:12
  • - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView { [self bilgileriYukle]; // Return the number of sections. return 1; } – mrtcnkryln Jul 10 '14 at 14:14
  • To use GCD take help from here -- http://stackoverflow.com/questions/15668160/asynchronous-downloading-of-images-for-uitableview-with-gcd – Yogendra Jul 10 '14 at 14:17
  • @Megioco you need to pull the data from the url in viewDidLoad and post it to an array, then use this array at cellForRowAtIndexPath method – erdemgc Jul 10 '14 at 14:26
  • There is a library named [SDWebimage](https://github.com/rs/SDWebImage), easy to use and best performance, it fetch images without blocking your user interface also cache images, whenever you call same image url it beings images from cache instead of fetching again and again. You should try that. – modusCell Jul 10 '14 at 14:44

3 Answers3

3

It's pretty easy and straightforward to load images synchronously in table view cells, however it's evil, because it would cause the lag when you scroll it, because it's actually trying to load and display the images as you're scrolling.

Therefore, you must avoid loading images synchronously, but asynchronously instead, using a different thread other than the main thread, so that the scrolling and loading + displaying images can be done dependently, avoiding any kind of lag.

This is possibly a duplicate question, since it's already been asked and there are tutorials out there, but since I myself always had a problem with this on my first iOS app and found it very confusing, I'm posting the answer here, hoping it's helpful.

Try adding something like this to your - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath:

// Get the filename to load.
NSString *imageFilename = [imageArray objectAtIndex:[indexPath row]];
NSString *imagePath = [imageFolder stringByAppendingPathComponent:imageFilename];

[[cell textLabel] setText:imageFilename];

dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);

dispatch_async(queue, ^{
    UIImage *image = [UIImage imageWithContentsOfFile:imagePath];

    dispatch_sync(dispatch_get_main_queue(), ^{
        [[cell imageView] setImage:image];
        [cell setNeedsLayout];
    });
});
Neeku
  • 3,646
  • 8
  • 33
  • 43
  • I am not sure that this works for filePath==URL, and if it did it most certanly wouldn't protect you from the timeouts, and you don't need [cell setNeedsLayout]; unless you are subclassing the UITableViewCell and doing the drawing on your own – AntonijoDev Jul 11 '14 at 07:23
2

dataWithContentsOfURL is blocking your main thread, that'w why the table is acting like it is. You should load images in back thread so that the main thread can handle UI without interruptions

NSURL *url = [NSURL URLWithString:link];
        NSURLRequest *urlRequest = [[NSURLRequest alloc] initWithURL:url cachePolicy:0 timeoutInterval:kTimeoutInterval];
[NSURLConnection sendAsynchronousRequest:urlRequest 
                                       queue:[NSOperationQueue mainQueue]
                           completionHandler:^(NSURLResponse *response, NSData *data, NSError *error) {
    UIImage *image = [[UIImage alloc] initWithData:self.activeDownload];
    // set to ImageView
    cell.ThumbImage.image = image;

    }];
AntonijoDev
  • 1,317
  • 14
  • 29
  • whats the timeoutInterval:kTimeoutInterval ill declare here or ill set time ? and activeDownload what is this ? – Gökhan Çokkeçeci Jul 11 '14 at 05:34
  • it is connection time out interval, if server becomes unresponsive or something like that, to prevent connection from hanging it will abort the operation in kTimeoutInterval time. set it to 20-30s or so. U don't want to set it to short because the download process duration depends on download data size and connection quality. So if you are on bad network even the small downloads could last for some time. So 20 s for an image is more than enough and if it doesn't finish by then, it most probably wont so it is ok to abort... – AntonijoDev Jul 11 '14 at 07:13
1
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{

    TableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:@"TableViewCell" forIndexPath:indexPath];

    cell.tag = indexPath.row;
    cell.imageView.image = nil;

    // Rounded Rect for cell image
    CALayer *cellImageLayer = cell.imageView.layer;
    [cellImageLayer setCornerRadius:35];
    [cellImageLayer setMasksToBounds:YES];


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


        NSData *data = [NSData dataWithContentsOfURL:[NSURL URLWithString:_ResimAdi[indexPath.row]]];
        UIImage *image = [[UIImage alloc] initWithData:data];

        if (image) {

            dispatch_async(dispatch_get_main_queue(), ^{
                if (cell.tag == indexPath.row) {

                    CGSize itemSize = CGSizeMake(70, 70);
                    UIGraphicsBeginImageContext(itemSize);
                    CGRect imageRect = CGRectMake(0.0, 0.0, itemSize.width, itemSize.height);
                    [image drawInRect:imageRect];
                    cell.imageView.image = UIGraphicsGetImageFromCurrentImageContext();
                    UIGraphicsEndImageContext();
                    [cell setNeedsLayout];

                }
            });
        }
    });

    cell.TitleLabel.text = _TarifAdi[indexPath.row];
    return cell;

}
Gökhan Çokkeçeci
  • 1,388
  • 3
  • 16
  • 37