Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>You may try the following code. You should also research your problem and try to find other existing answers and explanations. This is a very frequent question, countless times answered on SO ;)</p> <p>For example: <a href="https://stackoverflow.com/questions/11884093/loading-images-in-table-using-blocks-dispatch-async-return-value">loading images in table using blocks</a></p> <p>The code tries to fix the <em>most obvious</em> issues, but there is no guarantee that it works in all edge cases. You need to debug and test.</p> <p>The main problem with the original code is, that it tries to set the cell's <code>newsImage</code> property within the completion block. When that gets executed, the captured cell is likely not be associated to the same row anymore. Remember: cells will be reused!</p> <p>Thus, in the completion block, the changed code re-evaluates the corresponding cell, from the indexPath which has been captured at the start of the block:</p> <pre><code>NewsCell* cell2 = [tableView cellForRowAtIndexPath:indexPath]; // cell equals nil, if not visible </code></pre> <p>The returned cell may be not visible, in which case the table view returns nil.</p> <p>Basically, the same is applied to the <em>record</em> variable. Just for different reasons: the <em>record</em> variable is a variable with automatic scope, that is it gets released when the method returns. Capturing it in the block is probably not a good idea. </p> <p>Thus, it needs to be re-evaluted in the block. Thats basically a short hand for <code>[self.records objectAtIndex:[indexPath row]];</code></p> <pre><code>- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString *CellIdentifier = @"NewsCell"; NewsCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier]; // Configure the cell... NewsItem *item = [newsItemsArray objectAtIndex:indexPath.row]; cell.newsTitle.text = item.title; NSMutableDictionary *record = [_records objectAtIndex:[indexPath row]]; if ([record valueForKey:@"actualImage"]) { NSLog(@"Record Found"); [cell.newsImage setImage:[record valueForKey:@"actualImage"]]; } else { NSLog(@"Record Not Found"); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,(unsigned long)NULL), ^(void) { NSLog(item.image); NSData *imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:item.image]]; dispatch_async(dispatch_get_main_queue(), ^(void){ NSMutableDictionary *record2 = [_records objectAtIndex:[indexPath row]]; [record2 setValue:[UIImage imageWithData:imageData] forKey:@"actualImage"]; NewsCell* cell2 = [tableView cellForRowAtIndexPath:indexPath]; // cell equals nil, if not visible if (cell2) { [cell2.newsImage setImage:[record2 valueForKey:@"actualImage"]]; [tableView reloadRowsAtIndexPaths:[NSArray arrayWithObject:indexPath] withRowAnimation:UITableViewRowAnimationNone]; } }); }); } return cell; } </code></pre>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload