SORU
21 Mayıs 2013, Salı


Zaman uyumsuz görüntü kaydırma yaparken yanlış resim için UİTableView bir hücre - görüntü değişiklikleri içinde url yükleme

UİTableView benim hücre içinde yük resimler uyumsuz iki yolu yazdım. Her iki durumda da görüntü görüntü kaydırma sonuna kadar bir kaç kez değişecek ve görüntü sağ görüntü geri döner masa kaydırma yapacağım zaman güzel ama yükleyecektir. Bu neden oluyor hiçbir fikrim yok.

#define kBgQueue dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0)

- (void)viewDidLoad
{
    [super viewDidLoad];
    dispatch_async(kBgQueue, ^{
        NSData* data = [NSData dataWithContentsOfURL: [NSURL URLWithString:
                                                       @"http://myurl.com/getMovies.php"]];
        [self performSelectorOnMainThread:@selector(fetchedData:)
                               withObject:data waitUntilDone:YES];
    });
}

-(void)fetchedData:(NSData *)data
{
    NSError* error;
    myJson = [NSJSONSerialization
              JSONObjectWithData:data
              options:kNilOptions
              error:&error];
    [_myTableView reloadData];
}    

- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView {
    // Return the number of sections.
    return 1;
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section{
    // Return the number of rows in the section.
    // Usually the number of items in your array (the one that holds your list)
    NSLog(@"myJson count: %d",[myJson count]);
    return [myJson count];
}
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{

        myCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
        if (cell == nil) {
            cell = [[myCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
        }

        dispatch_async(kBgQueue, ^{
        NSData *imgData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://myurl.com/%@.jpg",[[myJson objectAtIndex:indexPath.row] objectForKey:@"movieId"]]]];

            dispatch_async(dispatch_get_main_queue(), ^{
        cell.poster.image = [UIImage imageWithData:imgData];
            });
        });
         return cell;
}

... ...

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

            myCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
            if (cell == nil) {
                cell = [[myCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
            }
    NSURL* url = [NSURL URLWithString:[NSString stringWithFormat:@"http://myurl.com/%@.jpg",[[myJson objectAtIndex:indexPath.row] objectForKey:@"movieId"]]];
    NSURLRequest* request = [NSURLRequest requestWithURL:url];


    [NSURLConnection sendAsynchronousRequest:request
                                       queue:[NSOperationQueue mainQueue]
                           completionHandler:^(NSURLResponse * response,
                                               NSData * data,
                                               NSError * error) {
                               if (!error){
                                   cell.poster.image = [UIImage imageWithData:data];
                                   // do whatever you want with image
                               }

                           }];
     return cell;
}

CEVAP
21 Mayıs 2013, Salı


Yapman gereken taktik hızlı bir düzeltme arıyorsanız varsayarak, hücre görüntü başlatıldı ve aynı zamanda hücre satır hala görünür, örneğin olduğundan emin olun

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

    myCell *cell = [tableView dequeueReusableCellWithIdentifier:@"cell"];
    if (cell == nil) {
        cell = [[myCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"cell"];
    }

    cell.poster.image = nil; // or cell.poster.image = [UIImage imageNamed:@"placeholder.png"];

    dispatch_async(kBgQueue, ^{
        NSData *imgData = [NSData dataWithContentsOfURL:[NSURL URLWithString:[NSString stringWithFormat:@"http://myurl.com/%@.jpg",[[myJson objectAtIndex:indexPath.row] objectForKey:@"movieId"]]]];
        if (imgData) {
            UIImage *image = [UIImage imageWithData:imgData];
            if (image) {
                dispatch_async(dispatch_get_main_queue(), ^{
                    myCell *updateCell = (id)[tableView cellForRowAtIndexPath:indexPath];
                    if (updateCell)
                        updateCell.poster.image = image;
                });
            }
        }
    });
    return cell;
}

Yukarıdaki kod iki sorunu hücre devşirme olmasından kaynaklanan adresleri:

  1. Arka plan istek (dequeued hücre için son görüntü hala orada olacak yani) sen başlamadan önce hücre görüntü başlatılıyor değilsin. Bunu sıfırlamak. Burada daha önemli bir sorun.

  2. Daha ince bir sorun, çok yavaş bir ağ üzerinde, zaman uyumsuz bir istek hücre ekranın dışına kaydırır önce bitirmek olmayabilir. 7* *UITableView yöntemi (benzer isimli UITableViewDataSource yöntemi tableView:cellForRowAtIndexPath: ile karıştırılmamalıdır) eğer bu satır için hücre hala görünür olup olmadığını görmek için kullanabilirsiniz. Bu yöntem, hücre görünmüyorsa nil dönecektir.

    Sorunu hücre zaman uyumsuz yöntemini tamamladı zaman kaydırılan ve daha kötü olan, hücre tablonun başka bir satır için yeniden olmuştur. Eğer satır hala görünür olup olmadığını görmek için kontrol ederek, yanlışlıkla beri ekranın dışına kaydırılan bir satır için resimle güncelleme kalmamasıdır.

    Bu yaklaşım aynı zamanda sendAsynchronousRequest yorumuyla, çok çalışır.

Daha iyi bir düzeltme olsa da, kullanmak için UIImageView kategori olarak verilir SDWebImage AFNetworking edecek, idare bu daha verimli iptal isteği ilerleme eğer hücrenin görüntüsü gibi oldu tekrar başka bir hücreye. Bir çok yavaş ağ, hızlı kaydırma ile ilk, örneğin, 50 resimler için ilk 50 satır tableview, uygulamanız (ki ben eskiden savunucusu kadar ben daha iyi takdir bu incelik) devam etmeye resimleri yükle bu yana kaydırılan ekran dışı yapma, çok yavaş cevap 51 resim ihtiyacınız için görünür hücre.

UIImageView bu kategoriler de senin kodu ile ek bir sorunu çözmek: cacheing. Gerçekten geri kaydırma yaptığınızda yeniden almak ağdan görüntü ve önceki satır bakmak istemiyorum. NSCache akılcı kullanımı bu kategorilerin kullanımı) önemli ölçüde performansını artırmak ve gereksiz ağ isteklerini azaltacaktır.

Eğer isterseniz, kendi imageview kategorinizi yazabilirsiniz, ama bir sürü iş var, ve SDWebImage AFNetworking zaten bunu senin için yaptı.

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • Jejoab

    Jejoab

    4 NİSAN 2008
  • Joshua Kywn

    Joshua Kywn

    17 Mayıs 2010
  • Max Lee

    Max Lee

    18 AĞUSTOS 2006