的cellForRowAtIndexPath始终无调用时从块内的tableView:的cellForRowAtIndexPath:

问题描述:

我有从的tableView调用时的cellForRowAtIndexPath总是返回零一个问题:的cellForRowAtIndexPath:的cellForRowAtIndexPath始终无调用时从块内的tableView:的cellForRowAtIndexPath:

事情是我实际调用的cellForRowAtIndexPath一个内内的tableView :cellForRowAtIndexPath:我想这可能是问题。

我使用加载(和缓存)ad hoc的远程图像填充单元格。当图像返回完全加载完成处理程序块(在tableView:cellForRowAtIndexPath :)内我需要再次获取该单元格,因为它可能已滚动出视图...所以我调用cellForRowAtIndexPath再次获取单元格 - cellForRowAtIndexPath将只返回一个单元如果它是可见的。在我的情况下,我从来没有得到它返回任何东西,但零。即使我滚动速度非常慢(或者速度很快,或者我试过的任何速度......)但我所得到的结果都是零。

我会尝试在这里得到一些代码,但在此之前有任何建议,为什么会发生这种情况 - 我想块的东西将是一个提示。

下面是代码:https://dl.dropboxusercontent.com/u/147970342/stackoverflow/appsappsappsappsapps.zip

的-tableView:的cellForRowAtIndexPath:实现:

-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    NSNumber* numberAppleid = self.appids[indexPath.row]; 
    UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:@"Mycell" forIndexPath:indexPath]; 

    cell.textLabel.text = [NSString stringWithFormat:@"Appleid: %@", numberAppleid]; 

    NSString* appleidasstring = [NSString stringWithFormat:@"%@", numberAppleid]; 

    cell.imageView.hidden = YES; // Hide any previous until image loads 
    [self getAppIconForAppleid:appleidasstring handlerImage:^(UIImage *image) { 
     if (image == nil) { 
      return; 
     } 

     DLog(@"cellForRowAtIndexPath tableView: %@, indexPath: %@", tableView, indexPath); 
     UITableViewCell* localcell = [tableView cellForRowAtIndexPath:indexPath]; 
     if (localcell != nil) { 
      localcell.imageView.image = image; 
      localcell.imageView.hidden = NO; 
     } 
     else { 
      DLog(@"Nah indexpath is not visible for: %@ because localcell is nil.", appleidasstring); 
     } 
    }]; 


    return cell; 
} 

修正版本:

#define KEYAPPLEID @"keyappleid" 
-(UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { 
    NSNumber* numberAppleid = self.appids[indexPath.row]; 
    UITableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:@"Mycell" forIndexPath:indexPath]; 

    cell.textLabel.text = [NSString stringWithFormat:@"Appleid: %@", numberAppleid]; 

    NSString* appleidasstring = [NSString stringWithFormat:@"%@", numberAppleid]; 

    [cell setAssociativeObject:appleidasstring forKey:KEYAPPLEID]; 

    cell.imageView.hidden = YES; // Hide any previous until image loads 
    [self getAppIconForAppleid:appleidasstring handlerImage:^(UIImage *image) { 
     if (image == nil) { 
      return; 
     } 

     NSString* currentappleidofcell = [cell associativeObjectForKey:KEYAPPLEID]; 
     if ([currentappleidofcell isEqualToString:appleidasstring]) { 
      cell.imageView.image = image; 
      cell.imageView.hidden = NO; 
     } 
     else { 
      DLog(@"Returning appleid: %@ is not matching current appleid: %@", appleidasstring, currentappleidofcell); 
     } 
    }]; 


    return cell; 
} 

,并且需要这一类:https://stackoverflow.com/a/10319083/129202

如果该块位于tableView:cellForRowAtIndexPath:回调内,则可以直接在该块中引用单元格。该块将自动保持单元格,直到块消失。但是,请小心保留周期。如果块由单元所有,则必须使用对单元的弱引用。

所以您的实现应该是这样的:

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath 
{ 
    NSNumber* numberAppleid = self.appids[indexPath.row]; 

    // Create your own UITableViewCell subclass that has an "appleidasstring" property 
    MyTableViewCell* cell = [tableView dequeueReusableCellWithIdentifier:@"Mycell" forIndexPath:indexPath]; 

    cell.textLabel.text = [NSString stringWithFormat:@"Appleid: %@", numberAppleid]; 

    NSString* appleidasstring = [NSString stringWithFormat:@"%@", numberAppleid]; 

    cell.imageView.hidden = YES; // Hide any previous until image loads 

    // Set the appleidasstring on the cell to be checked later 
    cell. getAppIconForAppleid:appleidasstring = appleidasstring; 

    // Modify the handler callback to also callback with the appleidasstring 
    [self 
     getAppIconForAppleid:appleidasstring 
     handlerImage:^(UIImage *image, NSString *imageAppleIdaString) 
     { 
      if (image == nil) { 
       return; 
      } 

      // Ensure the cell hasn't been repurposed for a 
      // different imageAppleIdaString 
      if ([cell.appleidasstring isEqualToString:imageAppleIdaString]) { 
       cell.imageView.image = image; 
       cell.imageView.hidden = NO; 
      } 
     } 
    ]; 

    return cell; 
} 
+0

的东西是电池不能重复使用,因为它可能已滚出视当块的回报。这是一个常见的错误,也是细胞需要重新获得的原因。但我会很快发布代码。 – Jonny

+0

这可以通过对单元格执行检查来确保它仍然代表刚刚完成下载的块的同一图像。例如,通过将URL存储到单元格上的图像。 – drewag

+0

这听起来像我应该尝试下一步。我发布代码:https://dl.dropboxusercontent.com/u/147970342/stackoverflow/appsappsappsappsapps.zip – Jonny