代码之家  ›  专栏  ›  技术社区  ›  Bernard

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

  •  0
  • Bernard  · 技术社区  · 9 年前

    我正在尝试设置三个 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"];
    

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

    5 回复  |  直到 9 年前
        1
  •  0
  •   bunty    9 年前

    检查此项:

    // 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++;
        }];
    }
    
        2
  •  0
  •   technerd    9 年前

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

        3
  •  0
  •   danh    9 年前

    我猜,问题真的是在获取可见行的同时,不要花费精力下载滚动位置以外的图像。

    该问题的解决方案是,当需要在 cellForRowAtIndexPath: 。关于这个想法有很多通用的内容。对于特定于解析的解决方案, 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];
    
        4
  •  0
  •   Alistra    9 年前

    你有一个问题,你试图做基于顺序的添加,其中你的块异步启动,所以它可以是随机的顺序。

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

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

        5
  •  0
  •   Marco    9 年前

    我也遇到了同样的问题,我的图片被下载了,但没有按应有的顺序出现,我的表格视图图片和标题不匹配。

    为了解决这个问题,我在Parse中的类中创建了一个列。com,则使用此名称保存每个下载的图像。

    名称ForImages必须与列标题相同,例如:

    • 标题=辣香肠和四块奶酪| nameForImage= 胡椒粉和四块奶酪
    • 标题-Muzzarella和菠菜|nameForImage=Muzzarela和菠菜

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

    我希望它能帮助你,或者点燃一个解决方案,祝你好运。