ASIHTTPRequest одновременная загрузка изображений в виде таблицы занимает время - PullRequest
0 голосов
/ 15 декабря 2011

Я использовал инфраструктуру ASIHTTPRequest в своем проекте для обработки всех задач, связанных с сетью.

У меня есть пользовательская ячейка с миниатюрой, которая поступает с веб-сервера, и там около 500 изображений, поэтому я должен повторно использовать эту ячейку, чтобы обработать ее. Благодаря повторному использованию ячейки при прокрутке таблицы мы можем видеть изображения предыдущих ячеек, которые будут заменены новыми.

Если сетевое соединение низкое, то оно хуже, так как загрузка изображения занимает много времени .. поэтому на этот раз вы можете увидеть неправильное изображение, в частности, из-за повторного использования ячейки, поэтому мне нужно найти способ, чтобы эта замена изображения не происходила быть видимым для пользователя.

Я использую метод ASIDownalod SharedCache.

EDIT

NSString *reuseIdentifier = @"offerCell";

BRZOfferCell *offerCell = (BRZOfferCell*)[tableView dequeueReusableCellWithIdentifier:reuseIdentifier];

if (offerCell==nil) {

    offerCell = [[[BRZOfferCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier celltype:kDealCellTypeDealsList] autorelease];
}

[offerCell setImage:[UIImage imageNamed:IMAGE_NO_IMAGE]];

//---get the letter in the current section---
//NSString *alphabet = [mDealsIndex objectAtIndex:[indexPath section]];

//---get all deals beginning with the letter---
NSString* lSectionIndex = [NSString stringWithFormat:@"%i",[indexPath section]];

NSMutableArray *deals = [mIndexedOffersDic objectForKey:lSectionIndex];


if ([deals count]>0) {
    //---extract the relevant deal from the deals array object---
    Offer* lOffer = [deals objectAtIndex:indexPath.row];

    [offerCell setOffer:lOffer];

    offerCell.accessoryView = UITableViewCellAccessoryNone;

    if (mTableView.dragging == NO && mTableView.decelerating == NO)
    {
        //Function : format image url to _thumb@2x.png and Initiate Image request download 
        //and set  cache policy
        [mListViewHelper InitImageRequest: lOffer.PromoImage indexPath: indexPath];
    }

}

return offerCell;

Ответы [ 4 ]

1 голос
/ 15 декабря 2011

Как вы сказали, UITableView повторно использует ячейки, чтобы работать хорошо, поэтому вам необходимо очистить ячейку перед повторным ее использованием, или она будет отображать неправильные данные.

Вы также должны использовать асинхронные вызовы и некоторыеделегирование для обновления ячеек.

Я бы на самом деле взял его на более высокий уровень и использовал бы NSOperationQueue, который позволяет вам устанавливать максимальное количество одновременных загрузок и отменять запросы при выходе из страницы.

Что выВозможно, вы захотите создать помощники данных

@protocol BookDataHelperDelegate <NSObject>
@required
- (void) bookDataHelperDidLoadImage:(BookDataHelper *)dataHelper;
@end

@interface BookDataHelper

@property (nonatomic, retian) UIImage *bookCover;
@property (nonatomic, retain) Book *book;
@property (nonatomic, assign) NSObject<BookDataHelperDelegate> *delegate;

- (void) fetchImageAsynchronouslyFromWebWithDelegate:(NSObject<BookDataHelperDelegate> *)delegate;

@end

Это будет способ перезагрузки данных в вашей таблице

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

    static NSString *SimpleTableIdentifier = @"SimpleTableIdentifier";
    CustomCell *cell = [tableView
    dequeueReusableCellWithIdentifier:SimpleTableIdentifier];
    if (cell == nil) 
    {
       cell = [[[CustomCell alloc]initWithStyle:UITableViewCellStyleDefault
       reuseIdentifier:SimpleTableIdentifier] autorelease];
    }

    BookDataHelper *dataHelper = [myArray objectAtIndex:indexPath.row];

    if (!dataHelper.bookCover)
    {
         [cell.imageView setImage:nil];
         [dataHelper fetchImageAsynchronouslyFromWebWithDelegate:self];
    } 
    else
    {
         [cell.imageView setImage:dataHelper.bookCover];
    }

    cell.bookTitleLabel.text = dataHelper.book.title;
    return cell;

}

- (void)bookDataHelperDidLoadImage:(BookDataHelper *)datahelper
{
   [tableView reloadDate];
   // here you would either reload the table completely
   // Or you could reload specific cells
}
0 голосов
/ 15 декабря 2011

Я использовал методы ASIDownloadCache для решения своей проблемы.На самом деле есть 2 решения для этой проблемы

  1. Установка собственного пути кеша вместо SharedCache, но я не пошел на это, потому что я уже использовал sharedCache и нашел другой эффективный метод, который будетне меняйте мою текущую реализацию

  2. В этом подходе я использовал 2 метода из методов ASIDownloadCache (на удивление, сайт ASIHTTPREquest не упомянул эти методы в своей краткой информации)

    2.1 Первый метод - (BOOL)isCachedDataCurrentForRequest:(ASIHTTPRequest *)request
    , чтобы проверить, кэширован ли этот конкретный URL-адрес изображения или нет, если да, используйте 2-й метод 2.2 - (NSData *)cachedResponseDataForURL:(NSURL *)url, чтобы получить кэшированное изображение, чтобы мы могли установить изображение в самой cellForRowAtIndexPath и вы не увидитеизображение, заменяющее проблему из-за возможности повторного использования ячейки.

Вот код:

// Customize the appearance of table view cells.
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath{
    NSString *reuseIdentifier = @"offerCell";


BRZOfferCell *offerCell = (BRZOfferCell*)[tableView dequeueReusableCellWithIdentifier:reuseIdentifier];

if (offerCell==nil) {

    offerCell = [[[BRZOfferCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:reuseIdentifier celltype:kDealCellTypeDealsList] autorelease];
}

[offerCell setImage:[UIImage imageNamed:IMAGE_NO_IMAGE]];

//---get the letter in the current section---
//NSString *alphabet = [mDealsIndex objectAtIndex:[indexPath section]];

//---get all deals beginning with the letter---
NSString* lSectionIndex = [NSString stringWithFormat:@"%i",[indexPath section]];

NSMutableArray *deals = [mIndexedOffersDic objectForKey:lSectionIndex];


if ([deals count]>0) {
    //---extract the relevant deal from the deals array object---
    Offer* lOffer = [deals objectAtIndex:indexPath.row];

    [offerCell setOffer:lOffer];

    offerCell.accessoryView = UITableViewCellAccessoryNone;

    if ([mListViewHelper isCached:lOffer.PromoImage]) { // Is image available in Cache ?

        // Image  is available use image fomr cache directly 
        [offerCell setImage:[UIImage imageWithData:[mListViewHelper cacheDataWithNSURL:lOffer.PromoImage]]];
    }
    else{
        //Function : Initiate Image request download and set cache policy

        if (mTableView.dragging == NO && mTableView.decelerating == NO)
            [mListViewHelper InitImageRequest: lOffer.PromoImage indexPath: indexPath];
    }
}

return offerCell;
}
0 голосов
/ 15 декабря 2011

в платформе ASIHTTPRequest он работает как с типом Synchronize, так и с ASynchronize, поэтому firat подскажет, какой из них вы используете для получения данных изображения, а также скажите, что вы отправляете 500 запросов на изображение за раз или отправляете согласно загруженной ячейке

или если вы отправляете запрос на 500 изображений за один раз, чем этот, это неправильно, в соответствии с требованием ячейки, отправьте запрос на то, что изображение ячейки, в противном случае, неосуществимо.

0 голосов
/ 15 декабря 2011

В вашем делегате ячейки табличного представления, когда вы получите повторно или новую ячейку, очистите изображение перед его возвратом.Обновление с соответствующим собственным загруженным изображением в асинхронном обратном вызове.Возможно, вы захотите убедиться, что изображения сохранены или сохранены где-то еще, хотя, если вы не хотите, чтобы ваше приложение продолжало перезагружать их.

...