Изображения из NSData загружаются неправильно - PullRequest
1 голос
/ 21 февраля 2012

Я пытаюсь загрузить изображения с NSData, извлеченные с сервера, и отобразить их в пользовательском UITableViewCell, но он работает неправильно и повторяет изображение снова и снова.

Table View

Вверху у нас есть indexPath.row = 0, идущий оттуда.Когда ячейка загружается, она вызывает следующий код для загрузки изображения (которое при использовании NSLog возвращает правильный URL-адрес для каждого изображения), поэтому, похоже, оно загружает правильное изображение.

- (void) startLoadingImage
{
    NSString *url = @"myurlhere";
    url = [url stringByAppendingFormat:identifier];
    NSLog(@"Image URL: %@", url); //THIS IS WHERE I DETERMINE THAT IT IS DOWNLOADING THE CORRECT IMAGE
    NSURLRequest * request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:url]];
    NSURLConnection * imageConnection = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    [imageConnection start];
}

Когда с сервера возвращается NSData, ячейка использует методы делегата ...

-(void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data
{
    if (!rawData) rawData=[[NSMutableData alloc]initWithLength:0];
    [rawData appendData:data];
}
-(void)connectionDidFinishLoading:(NSURLConnection *)connection
{
    NSLog(@"Image did finish loading. Displaying...");

    [productImage setImage:[[UIImage alloc]initWithData:rawData]];
}

Работает нормально, загружая четыре изображения, а затемначинает повторять изображения (хотя информация в ячейке, такая как имя и цена, отображается правильно).Это означает, что вы будете видеть фотографию джинсов снова и снова, каждые четыре ячейки.

Вот мой вывод NSLog.Опять же, похоже, все правильно.

2012-02-21 14:45:01.152 APPNAME[7873:11f03] Image URL: http://www.MYAPPURL.net/production/img/c_00084@2x.jpg
2012-02-21 14:45:01.173 APPNAME[7873:11f03] Image URL: http://www.MYAPPURL.net/production/img/c_00085@2x.jpg
2012-02-21 14:45:01.199 APPNAME[7873:11f03] Image did finish loading. Displaying...
2012-02-21 14:45:01.205 APPNAME[7873:11f03] Image did finish loading. Displaying...
2012-02-21 14:45:11.064 APPNAME[7873:11f03] Image URL: http://www.MYAPPURL.net/production/img/c_00086@2x.jpg
2012-02-21 14:45:11.476 APPNAME[7873:11f03] Image did finish loading. Displaying...
2012-02-21 14:45:12.432 APPNAME[7873:11f03] Image URL: http://www.MYAPPURL.net/production/img/c_00089@2x.jpg
2012-02-21 14:45:12.751 APPNAME[7873:11f03] Image URL: http://www.MYAPPURL.net/production/img/c_00080@2x.jpg
2012-02-21 14:45:13.010 APPNAME[7873:11f03] Image did finish loading. Displaying...
2012-02-21 14:45:13.013 APPNAME[7873:11f03] Image did finish loading. Displaying...
2012-02-21 14:45:14.574 APPNAME[7873:11f03] Image URL: http://www.MYAPPURL.net/production/img/c_00081@2x.jpg
2012-02-21 14:45:14.948 APPNAME[7873:11f03] Image did finish loading. Displaying...

Итак, как вы можете видеть, он загружает изображения 84, 85, 86, 89, 80, 81, но отображает только изображения 84, 85, 86, 89, а затем повторяет их.

Кто-нибудь знает, почему это происходит и почему?

Ответы [ 2 ]

4 голосов
/ 22 февраля 2012

UITableView повторно использует UITableViewCell объекты, которые вы создаете (с помощью метода dequeueReusableCellWithIdentifier:). Вы не должны изменять UITableViewCell объекты напрямую. Вместо этого перезагрузите данные таблицы, а затем обновите ячейки в методе делегата tableView:cellForRowAtIndexPath:.

В вашем контроллере вида у вас будет что-то вроде этого:

- (void) connectionDidFinishLoading:(NSURLConnection *)connection
{
    // set the product.image from the response data here

    // reload table
    [self.tableView reloadData];
}

Перезагрузка данных обновит ваши ячейки таблицы, что вызовет методы вашего делегата:

- (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    static NSString *cellIdentifier = @"CellId";

    UICustomTableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:cellIdentifier];
    if (cell == nil)
    {
        // create custom cell
        cell = [[[UICustomTableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:cellIdentifier] autorelease];
    }

    Product *product = [products objectAtIndex:indexPath.row];

    cell.textLabel.text = product.name;
    cell.image = product.image;

    return cell;
}
0 голосов
/ 22 февраля 2012

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

Я думаю, вы могли бы найти пример в Руководстве Рэя Вендерлиха по многопоточности и Grand Central Dispatch на iOS для начинающих очень хорошо подходит для того, что вы делаете.Я рекомендую вам внимательно изучить этот пример и посмотреть, сможете ли вы заставить его работать на вас.Вы можете скачать проект sampel (ссылка внизу страницы) и посмотреть, как он работает самостоятельно.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...