【问题标题】:Don't reload cell when scroll back向后滚动时不要重新加载单元格
【发布时间】:2013-10-16 12:54:16
【问题描述】:

我有一个在网络上找不到的问题。我必须显示一些从笔尖加载的自定义单元格。我在一个单独的线程上从我的数据库下载信息并将其分配到一个新的 MutableArray 上。 我也有图像分配在一个单独的数组中,并在必要时调用,但不是从网上下载的。 向下滚动时,我的表格视图“滞后”,那是(我猜)因为它必须将东西放在正确的单元格上,但是当我向后滚动时它再次滞后并重新加载所有信息。 我看到 Facebook 应用程序在向下滚动时加载单元格(但不是那么慢),当向后滚动时它不会重新加载任何内容并且单元格已经加载(无论有多少)。我怎么能做这样的事情?我的表很慢,我(目前)只有 3 个单元格。但是当应用程序完成时,这些单元格将是 100 或 200。 谁能帮帮我?

这是我的代码:(viewDidLoad 上的这个)

 NSString *strURL = [NSString stringWithFormat:@"..(myurl)..];
// to execute php code
NSData *dataURL = [NSData dataWithContentsOfURL:[NSURL URLWithString:[strURL stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding]]];
// to receive the returend value
NSString *strResult = [[NSString alloc] initWithData:dataURL encoding:NSUTF8StringEncoding];

if(![strResult isEqualToString:@"0"]) {
    posts = [strResult componentsSeparatedByString:@"^"];
}

immProfilo = [NSMutableArray array];

for (int i = 0; i < [posts count]; i++) {
    NSArray *datiPost = [[posts objectAtIndex:i] componentsSeparatedByString:@"/"];
    FBProfilePictureView *fotoProfiloFB = [[FBProfilePictureView alloc] initWithFrame:CGRectMake(22, 22, 55, 55)];
    fotoProfiloFB.profileID = [datiPost objectAtIndex:1];
    [immProfilo addObject:fotoProfiloFB];
}

[self.postTab reloadData];

这是我的表格视图代码:

- (NSInteger)numberOfSectionsInTableView:(UITableView *)postTab {

return [posts count];
}

- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section {
    return 1;
}

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
    NSString *CellIdentifier = [NSString stringWithFormat:@"%ld_%ld",(long)indexPath.section,(long)indexPath.row];

    PostTabCell *cell = (PostTabCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];

    if (cell == nil) {

        NSArray *topLevelObjects = [[NSBundle mainBundle] loadNibNamed:@"PostTabCell" owner:self options:nil];
        cell = [topLevelObjects objectAtIndex:0];
    }

    NSString *annuncio = [posts objectAtIndex:indexPath.section];
    datiAnnuncio = [annuncio componentsSeparatedByString:@"/"];

   [cell addSubview:[immProfilo objectAtIndex:indexPath.section]];

    cell.nome.text = [datiAnnuncio objectAtIndex:0];
    cell.location.text = [self getAddressFromLatLon:[[datiAnnuncio objectAtIndex:2] floatValue] withLongitude:[[datiAnnuncio objectAtIndex:3] floatValue]];
    cell.testoPost.text = [datiAnnuncio objectAtIndex:4];

    return cell;
}

【问题讨论】:

    标签: ios objective-c uitableview reload


    【解决方案1】:

    您的表格视图如此滞后的原因是,每次表格视图向委托请求一个单元格(您的cellForRowAtIndexPath 方法)时,您都会使用getAddressFromLatLon 执行同步网络请求,从而阻塞了主线程。

    一个直接的解决方法是-至少-将这些文本存储在某种数组中,这样下次表格视图请求同一个单元格时,您就不必执行网络再次请求。

    这将解决当您向上滚动时 tableview 滞后的问题,但在您第一次向下滚动时不会。您始终可以认为是正确的一条一般规则是,您永远不应该用网络请求阻塞主线程。

    您现在有两个选择:在显示微调器的同时在辅助线程上一开始就加载所有这些文本(这很简单,但存在一些问题,例如它不能很好地随着单元格的数量而扩展)。或者你必须设计一个异步加载器,它会显示一个占位符字符串,例如loading address...,直到地址被实际加载。

    Totumus 的回答也有道理,但这不是您滞后的主要原因(尽管一旦您的细胞数量增加,这将是一个大问题)。

    【讨论】:

    • 在视图生命周期开始时加载所有数据不是一个用户友好的解决方案。在单元格中加载数据的最佳方法是在后台线程中异步执行此操作。这是为了防止长时间等待和阻塞 UI。应缓存答案以防止需要更多的服务器调用。
    • addsubview: 每次重用/创建单元格时调用都会在滚动时产生大量延迟。不要忘记,每次新单元格进入屏幕时,您都会将该图像视图相互叠加。最后,当您滚动几次时,这些子视图的多个图层将加载到单元格上。
    • 我们可以同意这个代码有两个大问题:)
    • 当然可以。他希望缓存数据并且不知道这个过程是如何完成的;)
    • 如何缓存数据?好的位置我可以解决,但对于其他事情?本地数据库?我不知道如何提高我的应用程序的性能!有什么建议吗?
    【解决方案2】:

    您描述的延迟是由您不断添加到可重用单元格的图像视图引起的。每次单元格重新加载时,都会再次将图像视图添加到您的单元格中。

    防止addSubview: 之类的函数出现在您的cellForRowAtIndexPath: 中。 相反,您应该创建一个自定义单元格,该单元格已经包含您的个人资料图片所需的 UIImageView

    滚动时加载信息的原因是您可能会在每次创建/重用单元格时加载信息(getAddressFromLatLon:?)。这很好,但应该在单独的线程中完成(因此应该异步处理响应)。

    当您再次向上滚动时,您看到 facebook 不再加载的原因是因为它们在将数据加载到应用程序时缓存了数据。可能是 CoreData。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-26
      • 1970-01-01
      • 1970-01-01
      • 2013-08-29
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多