如何在 iOS Parse 中按顺序下载图片?

How to download images in order in iOS Parse?

我正在尝试设置三个 NSMutableArray 以在 UITableView 中使用。

这是我的代码:

for (PFObject *object in objects) {

    PFUser *user = (PFUser *) object[@"user"];

    [ [user objectForKey:@"image"] getDataInBackgroundWithBlock:^(NSData *data, NSError *error) {
        if (!error)
        {

            //Add Comment text
            [_commentsArray insertObject:[object objectForKey:@"comment"] atIndex:i];


            //Add comment Id
            [_commentIDArray insertObject:object.objectId atIndex:i];

            //Add user image
            [_picsArray insertObject:[UIImage imageWithData:data] atIndex:i ];

            if (i == [objects count]-1)
            {
                [self.tableView reloadData];

            }
        }
        else
        {
            NSLog(@"Errrror ==  %ld",(unsigned long)[_picsArray count]);
        }
        i++;
    }];
}

PFQuery我点的是:

[query orderByDescending:@"createdAt"];

但据我所知,第一行的图片很大。所以下载它需要时间。所以它进入第二个循环。尝试下载图像。体积小。下载完毕。添加到数组。现在第一张图片的下载已经完成。添加到数组但排在第二位。如何管理它以便它按顺序逐一添加项目?

无需下载图像并创建数组来填充表视图,您只需创建 PFObjects 数组并将其与 SDWebImage 一起用于异步图像下载而不会出现任何问题或阻塞 UI。

检查这个:

// initially, add place holder
for (int i=0; i<objects.count; i++) {
    [_commentsArray addObject:@""];
    [_commentIDArray addObject:@""];
    [_picsArray addObject:@""];
}

for (PFObject *object in objects) {

    PFUser *user = (PFUser *) object[@"user"];

    [ [user objectForKey:@"image"] getDataInBackgroundWithBlock:^(NSData *data, NSError *error) {
        if (!error)
        {

            NSInteger orderIndex = [objects indexOfObject:object];

            //Replace Comment text
            [_commentsArray replaceObjectAtIndex:[object objectForKey:@"comment"] atIndex:orderIndex];


            //Replace comment Id
            [_commentIDArray replaceObjectAtIndex:object.objectId atIndex:orderIndex];

            //Replace user image
            [_picsArray replaceObjectAtIndex:[UIImage imageWithData:data] atIndex:orderIndex ];


            if (i == [objects count]-1)
            {
                [self.tableView reloadData];

            }
        }
        else
        {
            NSLog(@"Errrror ==  %ld",(unsigned long)[_picsArray count]);
        }
        i++;
    }];
}

我猜这个问题实际上是关于在仍在获取可见行的情况下不花力气下载超出滚动位置的图像。

该问题的解决方案是在 cellForRowAtIndexPath: 中需要配置单元格时延迟加载图像。有很多关于这个想法的通用内容。对于 parse-specific 解,see PFImageView here.

要点是图像视图将负责加载和缓存文件中的图像。它将异步执行此操作,因此感知到的延迟会很低。只需将文件提供给图像视图,剩下的交给它...

您的 cellForRowAtIndexPath 将如下所示:

// just guessing that your "objects" array is the table's datasource
PFObject *object = self.objects[indexPath.row];
PFUser *user = (PFUser *) object[@"user"];

// put a PFImageView in the cell (in this case with a tag==32)
PFImageView *imageView = (PFImageView *)[cell viewWithTag:32];
imageView.image = [UIImage imageNamed:@”placeholder.png”];
imageView.file = [user objectForKey:@"image"];  // assuming this is a file attribute
[imageView loadInBackground];

您在尝试进行基于顺序的添加时遇到了问题,您的块异步触发,因此它可以按随机顺序排列。

您应该更改为字典或任何其他键控数据结构,并为您的评论和图片使用键(例如,使用评论 ID 作为键)。

还要仔细检查块的回调是否在主队列或任何串行队列上执行,因为如果不是,则需要添加锁。

我遇到了同样的问题,我的图片已下载但未按应有的顺序显示,我的 table 查看图片和标题不匹配。

为了解决这个问题,我在 Parse.com 中的 class 中创建了一个专门包含 nameForImages 的列,然后使用此名称保存每个下载的图像。

NameForImages 必须与用于列标题的名称相同,例如:

  • 标题 = 意大利辣香肠和四块奶酪 |名称图片= 意大利辣香肠和四块奶酪
  • 标题 - 马苏里拉奶酪和菠菜 | nameForImage = MuzzarellaAndSpinach
  • 等等...

这个技巧很适合解决我的问题,因为出现在单元格中的图像名称和标题很短,没有特殊字符。

希望对您有所帮助或提出解决方案,祝您好运。