Проблема с асинхронной загрузкой UITableView - PullRequest
0 голосов
/ 02 мая 2011

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

Подскажите, пожалуйста, в чем проблема с моим кодом:

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

    UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
    if (cell == nil) {
        cell = [[[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier] autorelease];
    }

    SearchObject *so = (SearchObject *)[_tableData objectAtIndex:indexPath.row];
    cell.textLabel.text = [[[[so tweet] stringByReplacingOccurrencesOfString:@"&quot;" withString:@"\""] stringByReplacingOccurrencesOfString:@"&lt;" withString:@"<"] stringByReplacingOccurrencesOfString:@"&gt;" withString:@">"];
    cell.detailTextLabel.text = [so fromUser];
    if (cell.imageView.image == nil) {
        NSURLRequest *req = [NSURLRequest requestWithURL:[NSURL URLWithString:[so userProfileImageURL]]];
        NSURLConnection *conn = [NSURLConnection connectionWithRequest:req delegate:self];
        [conn start];
    }
    if ([_cellImages count] > indexPath.row) {
        cell.imageView.image = [UIImage imageWithData:[_cellImages objectAtIndex:indexPath.row]];
    }
    return cell;
}
- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data {
    [_cellData appendData:data];
    [_cellImages addObject:_cellData];
}
- (void)connectionDidFinishLoading:(NSURLConnection *)connection {
    [self.tableView reloadData];
}

Ответы [ 2 ]

1 голос
/ 02 мая 2011

Вы добавляете данные из каждого загруженного изображения в один и тот же объект данных.Таким образом, в лучшем случае объект данных заканчивается данными для изображения # 1, за которыми сразу же следуют данные для изображения # 2 и т. Д .;декодер изображения, по-видимому, берет первое изображение в порции данных и игнорирует мусор после.Вы также, кажется, не знаете, что NSURLConnections 'connection:didReceiveData: не обязательно будет вызываться в том порядке, в котором были установлены подключения, что connection:didReceiveData: можно вызывать ноль или несколько раз для каждого подключения (и, вероятно, будет, если ваши изображения большенесколько кибибайт), и что tableView:cellForRowAtIndexPath: не гарантированно будет вызываться для каждой ячейки в таблице по порядку.Все это полностью испортит ваш массив _cellImages.

Чтобы сделать это правильно, вам нужно иметь отдельный экземпляр NSMutableData для каждого соединения и добавить его в свой массив _cellImagesтолько один раз и с правильным индексом для строки, а не с произвольным следующим доступным индексом.И затем в connection:didReceiveData: вам нужно выяснить правильный экземпляр NSMutableData для добавления;это можно сделать, используя объект соединения (обернутый в NSValue, используя valueWithNonretainedObject:) в качестве ключа в NSMutableDictionary, или используя objc_setAssociatedObject, чтобы присоединить объект данных к объекту соединения, или создав себе класс, который обрабатывает всеуправление NSURLConnection для вас и вручает вам объект данных, когда завершено.

0 голосов
/ 02 мая 2011

Я не знаю, вызывает ли это проблему или нет, но в вашем методе connection:didReceiveData: вы просто добавляете данные изображения в массив;Вы должны хранить данные изображения таким образом, чтобы вы могли связать их с ячейкой, в которой они должны отображаться. Один из способов сделать это - использовать NSMutableArray, заполненный группой [NSNull] s, а затем заменитьзначение null в соответствующем индексе после завершения загрузки соединения.

Кроме того, вы добавляете _cellData к массиву _cellImages, когда подключение не завершило загрузку, следуетделать это в методе connection:didFinishLoading.

...