Reputation: 5044
I am trying to load images from NSData
pulled from a server and display them in a custom UITableViewCell
, but it is not working correctly and it is repeating the image over and over.
At the top we have indexPath.row = 0
, going up from there. When the cell loads, it calls the following code to load the image (which when using NSLog returns the correct URL for every image), so it does seem to be downloading the correct image.
- (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];
}
When the NSData
is returned from the server, the cell uses the delegate methods...
-(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]];
}
It works fine up to loading four images, and then it starts repeating the images (though the information in the cell like the name and price does show up correctly). This means that you would see the photo of the jeans over and over, every four cells.
Here is my NSLog
output. Again, it looks like everything is correct.
2012-02-21 14:45:01.152 APPNAME[7873:11f03] Image URL: http://www.MYAPPURL.net/production/img/[email protected]
2012-02-21 14:45:01.173 APPNAME[7873:11f03] Image URL: http://www.MYAPPURL.net/production/img/[email protected]
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/[email protected]
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/[email protected]
2012-02-21 14:45:12.751 APPNAME[7873:11f03] Image URL: http://www.MYAPPURL.net/production/img/[email protected]
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/[email protected]
2012-02-21 14:45:14.948 APPNAME[7873:11f03] Image did finish loading. Displaying...
So as you can see, it is loading images 84, 85, 86, 89, 80, 81, but it is only displaying images 84, 85, 86, 89, and then it repeats them.
Does anyone know why this is happening and why?
Upvotes: 1
Views: 531
Reputation: 5960
Without seeing all of your code, I think you might be having a problem with handling this as an asynchrounous connection. I don't see how you bind any particular cell to a connection request.
I think you might find the example in Ray Wenderlich's Multithreading and Grand Central Dispatch on iOS for Beginners Tutorial to be a very good fit for what you appear to be doing. I recomment that you look this example over carefully and see if you can make it work for you. YOu can download the sampel project (link near the bottom of that page) and see how it works yourself.
Upvotes: 0
Reputation: 6006
UITableView
reuses the UITableViewCell
objects that you create (via the dequeueReusableCellWithIdentifier:
method). You shouldn't modify the UITableViewCell
objects directly. Instead, reload the table data and then update the cells in the tableView:cellForRowAtIndexPath:
delegate method.
In your view controller, you would have something like this:
- (void) connectionDidFinishLoading:(NSURLConnection *)connection { // set the product.image from the response data here // reload table [self.tableView reloadData]; }
Reloading data will refresh your table cells, which will call your delegate methods:
- (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; }
Upvotes: 4