Objective c 我有80-90%的时间可以查看的图像,因为它们不';不能总是足够快地填充数据源。我怎样才能解决这个问题?

Objective c 我有80-90%的时间可以查看的图像,因为它们不';不能总是足够快地填充数据源。我怎样才能解决这个问题?,objective-c,cocoa-touch,uiviewcontroller,uiimage,nsmutablearray,Objective C,Cocoa Touch,Uiviewcontroller,Uiimage,Nsmutablearray,我有一个详细视图控制器,它由一个充满项目的集合视图控制器显示。这些物品中有些只有一张图片,有些有附加图片(衣服不同角度的图片) 当我切换到细节视图控制器时,我必须快速与外部数据库通信。首先,我检查是否有其他图像,并将它们存储在NSMutableArray中 数组填充图像的速度不够快,因此我必须在ViewDidAspect方法中重新加载数据 这在80-90%的情况下都能正常工作,但有时也会出现这样的情况,我只看到了旋转器,但没有图像。然后,我必须返回一个控制器,并返回到细节视图控制器,以便图像显示

我有一个详细视图控制器,它由一个充满项目的集合视图控制器显示。这些物品中有些只有一张图片,有些有附加图片(衣服不同角度的图片)

当我切换到细节视图控制器时,我必须快速与外部数据库通信。首先,我检查是否有其他图像,并将它们存储在NSMutableArray中

数组填充图像的速度不够快,因此我必须在ViewDidAspect方法中重新加载数据

这在80-90%的情况下都能正常工作,但有时也会出现这样的情况,我只看到了旋转器,但没有图像。然后,我必须返回一个控制器,并返回到细节视图控制器,以便图像显示。这是我的应用程序中唯一明显的问题。我不认为这是一个好的外观和肯定有一个办法来阻止这一点

我想可能在应用程序第一次打开时加载了所有资源。因此,加载背景中的所有图像。然而,随着客户商店的增长,他们的商店里有数千件衣服,会发生什么呢。可能是个问题。我还考虑过在前一个控制器中加载图像,但我知道在数组中加载和存储哪组图像的唯一方法是点击collection view单元格。如果客户到达页面并直接点击图像,阵列可能还没有准备好

以下是我如何加载图像并将其存储在阵列中。

- (void)viewDidLoad
{
    [super viewDidLoad];

    // Load up additional images
    PFQuery *query = [PFQuery queryWithClassName:@"Garments"];
    [query whereKey:@"title" equalTo:[self garmentTitle]];
    [query getFirstObjectInBackgroundWithBlock:^(PFObject *object, NSError *error) {

        [[self carouselSpinner] startAnimating];
        if (!error) {

            // Set objectID for save to favourite feature
            _garmentObject = object;

            PFFile *additionalImage1 = [object objectForKey:@"image2"];
            PFFile *additionalImage2 = [object objectForKey:@"image3"];
            PFFile *additionalImage3 = [object objectForKey:@"image4"];
            PFFile *additionalImage4 = [object objectForKey:@"image5"];
            PFFile *additionalImage5 = [object objectForKey:@"image6"];

            [_additionalGarmentImagesArray addObject:[self garmentImage]];

            if (additionalImage1) {

                PFImageView *pfImageView1 = [[PFImageView alloc] init];
                [pfImageView1 setFile:additionalImage1];
                [pfImageView1 loadInBackground:^(UIImage *image, NSError *error) {
                    if (!error) {
                        [_additionalGarmentImagesArray addObject:image];

                    }

                }];
            }

            if (additionalImage2) {

                PFImageView *pfImageView2 = [[PFImageView alloc] init];
                [pfImageView2 setFile:additionalImage2];
                [pfImageView2 loadInBackground:^(UIImage *image, NSError *error) {
                    if (!error) {
                        [_additionalGarmentImagesArray addObject:image];
                    }

                }];
            }

            if (additionalImage3) {

                PFImageView *pfImageView3 = [[PFImageView alloc] init];
                [pfImageView3 setFile:additionalImage3];
                [pfImageView3 loadInBackground:^(UIImage *image, NSError *error) {
                    if (!error) {
                        [_additionalGarmentImagesArray addObject:image];
                    }

                }];
            }

            if (additionalImage4) {

                PFImageView *pfImageView4 = [[PFImageView alloc] init];
                [pfImageView4 setFile:additionalImage4];
                [pfImageView4 loadInBackground:^(UIImage *image, NSError *error) {
                    if (!error) {
                        [_additionalGarmentImagesArray addObject:image];
                    }

                }];
            }

            if (additionalImage5) {

                PFImageView *pfImageView5 = [[PFImageView alloc] init];
                [pfImageView5 setFile:additionalImage5];
                [pfImageView5 loadInBackground:^(UIImage *image, NSError *error) {
                    if (!error) {
                        [_additionalGarmentImagesArray addObject:image];
                    }

                }];
            }



        } else {
            NSLog(@"emp array");
        }
数组由调用此方法的时间填充:

-(void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [[self carousel] reloadData];
}
- (NSInteger)numberOfItemsInCarousel:(iCarousel *)carousel
{
    //return the total number of items in the carousel

    return [_additionalGarmentImagesArray count];
}
- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSInteger)index reusingView:(UIView *)view
{


    PFImageView *imageView = [[PFImageView alloc] initWithFrame:CGRectMake(0, 0, 300.0f, 354)];
    view = imageView;

    //create new view if no view is available for recycling
    if (view == nil)
    {
        //set image
        ((PFImageView *)view).image = _additionalGarmentImagesArray[index];
        [[self carouselSpinner] stopAnimating];
    } else {
        //set image
        ((PFImageView *)view).image = _additionalGarmentImagesArray[index];
        [[self carouselSpinner] stopAnimating];
    }


    return view;
}
最后,我使用我的图像数组:

-(void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [[self carousel] reloadData];
}
- (NSInteger)numberOfItemsInCarousel:(iCarousel *)carousel
{
    //return the total number of items in the carousel

    return [_additionalGarmentImagesArray count];
}
- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSInteger)index reusingView:(UIView *)view
{


    PFImageView *imageView = [[PFImageView alloc] initWithFrame:CGRectMake(0, 0, 300.0f, 354)];
    view = imageView;

    //create new view if no view is available for recycling
    if (view == nil)
    {
        //set image
        ((PFImageView *)view).image = _additionalGarmentImagesArray[index];
        [[self carouselSpinner] stopAnimating];
    } else {
        //set image
        ((PFImageView *)view).image = _additionalGarmentImagesArray[index];
        [[self carouselSpinner] stopAnimating];
    }


    return view;
}
这里:

-(void)viewDidAppear:(BOOL)animated
{
    [super viewDidAppear:animated];
    [[self carousel] reloadData];
}
- (NSInteger)numberOfItemsInCarousel:(iCarousel *)carousel
{
    //return the total number of items in the carousel

    return [_additionalGarmentImagesArray count];
}
- (UIView *)carousel:(iCarousel *)carousel viewForItemAtIndex:(NSInteger)index reusingView:(UIView *)view
{


    PFImageView *imageView = [[PFImageView alloc] initWithFrame:CGRectMake(0, 0, 300.0f, 354)];
    view = imageView;

    //create new view if no view is available for recycling
    if (view == nil)
    {
        //set image
        ((PFImageView *)view).image = _additionalGarmentImagesArray[index];
        [[self carouselSpinner] stopAnimating];
    } else {
        //set image
        ((PFImageView *)view).image = _additionalGarmentImagesArray[index];
        [[self carouselSpinner] stopAnimating];
    }


    return view;
}
我突然想到的另一件事是,在我上一个控制器的序列中,我可以在后台从后端获取数据,并使用一个完成块。因此,如果抓取了数据,则转到详图视图控制器;如果没有,则不执行任何操作。在等待过程中,将显示一个微调器

你会如何处理我的问题

现在,每个图像都存储在数据库中自己的列中,例如image2、image3、image4、image5。我又在想也许把它们存储在一个数组里?但我不确定这能为我赢得多少时间,也不确定这是否能解决我在加载失败时遇到的问题。“我的收藏”视图图像是从后端拍摄到的,但它们从来都不会加载失败

如果可能的话,请提供一些可靠的建议或解决方案


感谢您抽出时间

我建议您首先从服务器获取要显示的所有图像的URL,以便您知道要在表视图或集合视图中配置多少单元格

然后使用UIImageView属性创建自定义单元格,以显示缩略图等。 另外,另一个属性NSDictionary*imageInfo;您将使用不同的详细信息设置,包括对应单元格图像的URL。 当您从视图控制器类设置imageInfo属性时,cell对象将异步(在后台)下载图像。为此,请重写imageInfo属性的setter

下载图像后,需要在主线程中更新UI(这在自定义单元格中完成):

这样,每当图像下载完成时,UI都会得到更新

如果需要,还可以缓存图像,还可以不时清除缓存

你可以考虑当细胞从屏幕上消失时调用的方法,在这种情况下,你可以取消任何下载,因为显然,如果不可见,你就不再需要它了。


希望它有意义

从我的理解来看,您希望确保
[[self carousel]reloadData]pfImageViewX loadInBackground:
background方法完成后始终调用code>,是否正确

我会这样做,我不会改变太多:

我会在您的后台提取中添加一个名为
numImagesChecked
的计数器,并在检查了5幅图像后将其递增

然后,我将包装
[[self carousel]reloadData]
在另一个函数中,仅当
numImagesChecked
为5时才会执行重新加载数据(即,检查并完成所有附加图像)

在这里,它在viewDidLoad中被修改:

[query getFirstObjectInBackgroundWithBlock:^(PFObject *object, NSError *error) {

        [[self carouselSpinner] startAnimating];
        if (!error) {

            // Set objectID for save to favourite feature
            _garmentObject = object;

            PFFile *additionalImage1 = [object objectForKey:@"image2"];
            PFFile *additionalImage2 = [object objectForKey:@"image3"];
            PFFile *additionalImage3 = [object objectForKey:@"image4"];
            PFFile *additionalImage4 = [object objectForKey:@"image5"];
            PFFile *additionalImage5 = [object objectForKey:@"image6"];

            [_additionalGarmentImagesArray addObject:[self garmentImage]];

            int numImagesChecked = 0; //add this

            if (additionalImage1) {

                PFImageView *pfImageView1 = [[PFImageView alloc] init];
                [pfImageView1 setFile:additionalImage1];
                [pfImageView1 loadInBackground:^(UIImage *image, NSError *error) {
                    if (!error) {
                        [_additionalGarmentImagesArray addObject:image];

                    }
                    numImagesChecked++;
                    [self performSelectorOnMainThread:@selector(reloadDataWithCounter:) withObject:[NSNumber numberWithInt:numImagesChecked] waitUntilDone:NO];
                }];
            }
            else {
                numImagesChecked++;
            }

            if (additionalImage2) {

                PFImageView *pfImageView2 = [[PFImageView alloc] init];
                [pfImageView2 setFile:additionalImage2];
                [pfImageView2 loadInBackground:^(UIImage *image, NSError *error) {
                    if (!error) {
                        [_additionalGarmentImagesArray addObject:image];
                    }
                    numImagesChecked++;
                    [self performSelectorOnMainThread:@selector(reloadDataWithCounter:) withObject:[NSNumber numberWithInt:numImagesChecked] waitUntilDone:NO];
                }];
            }
            else {
                numImagesChecked++;
            }

            if (additionalImage3) {

                PFImageView *pfImageView3 = [[PFImageView alloc] init];
                [pfImageView3 setFile:additionalImage3];
                [pfImageView3 loadInBackground:^(UIImage *image, NSError *error) {
                    if (!error) {
                        [_additionalGarmentImagesArray addObject:image];
                    }
                    numImagesChecked++;
                    [self performSelectorOnMainThread:@selector(reloadDataWithCounter:) withObject:[NSNumber numberWithInt:numImagesChecked] waitUntilDone:NO];
                }];
            }
            else {
                numImagesChecked++;
            }

            if (additionalImage4) {

                PFImageView *pfImageView4 = [[PFImageView alloc] init];
                [pfImageView4 setFile:additionalImage4];
                [pfImageView4 loadInBackground:^(UIImage *image, NSError *error) {
                    if (!error) {
                        [_additionalGarmentImagesArray addObject:image];
                    }
                    numImagesChecked++;
                    [self performSelectorOnMainThread:@selector(reloadDataWithCounter:) withObject:[NSNumber numberWithInt:numImagesChecked] waitUntilDone:NO];
                }];
            }
            else {
                numImagesChecked++;
            }

            if (additionalImage5) {

                PFImageView *pfImageView5 = [[PFImageView alloc] init];
                [pfImageView5 setFile:additionalImage5];
                [pfImageView5 loadInBackground:^(UIImage *image, NSError *error) {
                    if (!error) {
                        [_additionalGarmentImagesArray addObject:image];
                    }
                    numImagesChecked++;
                    [self performSelectorOnMainThread:@selector(reloadDataWithCounter:) withObject:[NSNumber numberWithInt:numImagesChecked] waitUntilDone:NO];
                }];
            }
            else {
                numImagesChecked++;
            }

            [self performSelectorOnMainThread:@selector(reloadDataWithCounter:) withObject:[NSNumber numberWithInt:numImagesChecked] waitUntilDone:NO];



        } else {
            NSLog(@"emp array");
        }
以下是新功能:

-(void)reloadDataWithCounter:(NSNumber *)imagesChecked
{
    if([imagesChecked intValue]>4){ //only reload data after all 5 images have been checked
        [[self carousel] reloadData];
    }
}

我同意@Pavlusha-使用PFFile对象中的URL。然后,您可以利用出色的AFUIImageView异步加载图像。

为了解决这个问题,我加载了其他图像,并将它们存储在collectionView(显示detailView的控制器)的cellForItemAtIndexPath方法中的数组中


然后,在segue过程中,我将该数组传递给了我的detailView的一个属性,我的图像数组立即可用。

但PFImageView视图正是这样做的。它异步加载图像。问题是有时可能有4个图像,有时可能有2个。管理员为那件衣服上传了多少额外的图片,这确实是不一样的。因此,我想知道如何计算返回对象中的额外图像数量,例如if additionlImage1、if additionalImage2等,然后将其与_additionalGarmentImagesArray进行比较,一旦匹配,这意味着加载了所有图像。然后我可以重新加载数据。基本上,我需要一种方法,让你上面提供的代码工作,如果我们不知道有多少图像将返回,因为数量不同。你不总是检查5个图像虽然?即使只有1、2或0,你也总是在检查5,对吗?计数器总是在5点结束。这并不是要计算有多少图像,只是检查了多少图像。这就是为什么每次图像检查时,它也会在“else”上递增。我使用PFImageView来执行上面所述的操作。