Tôi hiện đang cố gắng tải danh sách UITableView của Flickr Photo (cs193p iOS Stanford, bài tập 5). Để tránh sự kiện chặn giao diện người dùng, tôi đã hoãn tải xuống hình thu nhỏ của từng ô thành một hàng đợi khác (nhưng hãy cập nhật giao diện người dùng trở lại trong hàng đợi chính). Mã này không tải không đồng bộ các hình ảnh, mặc dù không thêm hình thu nhỏ khi tôi nhấp vào hàng UITableViewCell. (xem ảnh chụp màn hình bên dưới). Bất kỳ ý tưởng những gì tôi đang làm sai?Không đồng bộ UITableViewCell Tải hình ảnh bằng cách sử dụng GCD
PS: Tôi đã xem xét một số câu hỏi về Stackoverflow khác & Ví dụ về LazyTableImages của Apple, nhưng tôi vẫn tin rằng đây là cách sạch nhất để đạt được kết quả mong muốn.
Cảm ơn!
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Photo List Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// Configure the cell
NSDictionary *photo = [self.photoList objectAtIndex:indexPath.row];
if (photo != nil) {
if ([[photo objectForKey:@"title"] length] > 0) {
cell.textLabel.text = [photo objectForKey:@"title"];
} else if ([[[photo objectForKey:@"description"] objectForKey:@"_content"] length] > 0) {
cell.textLabel.text = [[photo objectForKey:@"description"] objectForKey:@"_content"];
} else {
cell.textLabel.text = @"Unknown";
}
}
cell.imageView.image = [[UIImage alloc] initWithCIImage:nil];
// Fetch using GCD
dispatch_queue_t downloadThumbnailQueue = dispatch_queue_create("Get Photo Thumbnail", NULL);
dispatch_async(downloadThumbnailQueue, ^{
UIImage *image = [self getTopPlacePhotoThumbnail:photo];
dispatch_async(dispatch_get_main_queue(), ^{
if ([self.tableView.visibleCells containsObject:cell]) {
[cell.imageView setImage:image];
}
});
});
dispatch_release(downloadThumbnailQueue);
return cell;
}
Trước khi nhấp chuột vào một hàng
Sau khi chọn hàng
UPDATE: Đối với những người quan tâm, đây là mã cuối cùng tôi đã sử dụng:
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
static NSString *CellIdentifier = @"Photo List Cell";
UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
// Configure the cell
NSDictionary *photo = [self.photoList objectAtIndex:indexPath.row];
if (photo != nil) {
if ([[photo objectForKey:@"title"] length] > 0) {
cell.textLabel.text = [photo objectForKey:@"title"];
} else if ([[[photo objectForKey:@"description"] objectForKey:@"_content"] length] > 0) {
cell.textLabel.text = [[photo objectForKey:@"description"] objectForKey:@"_content"];
} else {
cell.textLabel.text = @"Unknown";
}
}
cell.imageView.image = [[UIImage alloc] initWithCIImage:nil];
// Fetch using GCD
dispatch_queue_t downloadThumbnailQueue = dispatch_queue_create("Get Photo Thumbnail", NULL);
dispatch_async(downloadThumbnailQueue, ^{
UIImage *image = [self getTopPlacePhotoThumbnail:photo];
dispatch_async(dispatch_get_main_queue(), ^{
UITableViewCell *cellToUpdate = [self.tableView cellForRowAtIndexPath:indexPath]; // create a copy of the cell to avoid keeping a strong pointer to "cell" since that one may have been reused by the time the block is ready to update it.
if (cellToUpdate != nil) {
[cellToUpdate.imageView setImage:image];
[cellToUpdate setNeedsLayout];
}
});
});
dispatch_release(downloadThumbnailQueue);
return cell;
}
Hey, đây hoàn toàn là chủ đề, nhưng tự hỏi nếu bên trong khối bạn gửi đến chủ đề chính, thay vì kiểm tra đối tượng bình đẳng trên 'ô', kiểm tra xem một ô tại' indexPath' có tồn tại không? –
Tôi chỉ thử điều này: if ([self.tableView cellForRowAtIndexPath: indexPath]! = Nil) {... etc} và nó cũng hoạt động tốt. Đó là những gì bạn có trong tâm trí? – sybohy
Phải và không sử dụng 'cell.imageView' trực tiếp trong khối của bạn mà là lấy ô ở' indexPath' và sử dụng chế độ xem hình ảnh của nó. Tôi nghĩ rằng bạn có thể gặp vấn đề với việc tái sử dụng ô nếu bạn sử dụng 'ô' trực tiếp theo cách nó được sắp xếp bên trong khối chuỗi chính của bạn. –