2012-04-10 34 views
2

Ich habe eine UITableView mit einer benutzerdefinierten Zelle, die ich füllen (mit Array-Infoservices) nach dem Parsen der XML-Daten.Verzögerung beim Aktualisieren von UITableView benutzerdefinierte Zelle

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

    ApplicationCell *cell = (ApplicationCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier]; 
     if (cell == nil) { 
      [self.cellNib instantiateWithOwner:self options:nil]; 
      cell = tmpCell; 
      self.tmpCell = nil;   
     }  

     infoService *e = [self.infoservices objectAtIndex:indexPath.row]; 

     cell.name = [e infoName]; 

     NSString *infodetails = [e infoDetails]; 

     if (infodetails == nil) { 
      cell.details = @"Loading..."; 
      [self startInfoDownload:e forIndexPath:indexPath]; 

      NSLog(@"Loading..."); 
     } else { 
      cell.details = infodetails; 
      NSLog(@"Show info detail: %@", infodetails); 
     } 
     return cell; 
} 


- (void)infoDidFinishLoading:(NSIndexPath *)indexPath 
{ 
    infoDownloader *infoserv = [imageDownloadsInProgress objectForKey:indexPath]; 
    if (infoserv != nil) 
    { 

     [infoservices replaceObjectAtIndex:[indexPath row] withObject:infoserv.appRecord]; 

     NSIndexPath *a = [NSIndexPath indexPathForRow:indexPath.row inSection:0]; // I wanted to update this cell specifically 
     ApplicationCell *cell = (ApplicationCell *)[self.tableView cellForRowAtIndexPath:a]; 
     cell.details = [[infoservices objectAtIndex:[indexPath row]] infoDetails]; 

     NSLog(@"Updating=%@", [[infoservices objectAtIndex:[indexPath row]] infoDetails]); 
    } 
} 

Für jede Zelle Ich verwende NSURLConnection sendAsynchronousRequest abrufen und XML-Daten aus Objekt infoDownloader mit

- (void)startDownload 

für jede einzelne Zelle zu analysieren.

Nach Daten wurde erfolgreich analysiert Delegatmethode von infoDownloader

genannt wird
- (void)infoDidFinishLoading:(NSIndexPath *)indexPath 

Das Problem ist, dass, während die

- (void)infoDidFinishLoading:(NSIndexPath *)indexPath 

nach dem Parsen jede Zelle aufgerufen wird und ich die

sehen
NSLog(@"Updating=%@", [[infoservices objectAtIndex:[indexPath row]] infoDetails]); 

im Debugger mit den richtigen Details, die Zelle d oes nicht sofort erfrischt aber nach 6 oder 7 Sekunden. Auch ist cellForRowAtIndexPath nicht von

- (void)infoDidFinishLoading:(NSIndexPath *)indexPath 

aus irgendeinem Grunde aufgerufen, weil es nicht Debug-Ausgabe nach dem infoDidFinishLoading ist. Außerdem verstehe ich nicht, wie die cell.details tatsächlich aktualisiert wird, da cellForRowAtIndexPath nicht erneut aufgerufen wird.

Ich habe versucht, diese Funktion mit Apples LazyTableImages laden Beispiel, das ich erfolgreich verwendet habe, aber ich weiß nicht, was schief geht.

Antwort

0

Möglicherweise müssen Sie reloadRowsAtIndexPaths aufrufen, sobald die Daten geladen wurden. Was passieren könnte, ist, dass die Zellendaten geladen wurden, aber die Zellenzeichnung nicht aktualisiert wird.

Auch glaube ich, Ihr Code kann mehrfach die gleichen Daten fordern, denn wenn [e infoDetails] ist nil ein Antrag gestellt wird, aber die Zelle mehrmals angefordert werden kann, bevor die Daten geladen wird, so würde [self startInfoDownload:e forIndexPath:indexPath] mehrmals aufgerufen werden, die gleichen Download Daten. Sie sollten nachverfolgen, für welche Zeilen Sie Daten angefordert haben.

Schauen Sie sich diesen Code für einige Ideen, wie dieses Problem zu lösen: https://github.com/kgn/Spectttator/blob/master/SpectttatorTest-iOS/RootViewController.m#L123

0

Änderungen UI betreffen, müssen auf Haupt-Thread ausgeführt werden.

Aktualisieren von tableView, durch Ändern von Zellen Details, realoading Tabe-Ansicht, realoding Zeilen ... sind Änderungen, die die Benutzeroberfläche beeinflussen.

Insbesondere sollten Sie Ihre Änderungen im Hauptthread mit ausführen:

dispatch_async(dispatch_get_main_queue(), ^{ 
    cell.details = [[infoservices objectAtIndex:[indexPath row]] infoDetails]; 
} 

oder vor iOS 4:

cell performSelectorOnMainThread:@selector(setDetails:) withObject:[[infoservices objectAtIndex:[indexPath row]] infoDetails]; 
Verwandte Themen