图像不显示在预加载的UIImageView。

时间:2022-09-01 09:36:26

When app launches I add UIImageViews to screen with no image. Then I load image one by one using NSThread and set it for those views. The UiImageViews remain blank until after all images have been loaded and the thread finishes. Why doesn't the image show as soon as I set it for the UIImageView, why does it wait for NSThread to end?

当应用程序启动时,我将UIImageViews添加到没有图像的屏幕上。然后我使用NSThread将图像一个一个地加载,并设置为这些视图。在加载所有映像和线程完成后,UiImageViews仍然是空白的。为什么在我为UIImageView设置图像时,为什么它不显示,为什么它等待NSThread结束?

To add image views :

添加图像视图:

for(i = value; i < val; i++){
    UIButton *newbutton = [UIButton buttonWithType:UIButtonTypeCustom];
    [newbutton setBackgroundColor:[UIColor whiteColor]];
    UIImageView *newback = [[UIImageView alloc] init];
    newback.contentMode = UIViewContentModeScaleAspectFit;
    [newback setFrame:CGRectMake(0, 0, 140, 140)];
    [newbutton addSubview:newback];
    height = MIN(300, newSize.height);
    [newbutton setFrame:CGRectMake(currentX, currentY, width, height)];
    newbutton.layer.cornerRadius = 10;
    newbutton.clipsToBounds = YES;
    [newbutton addTarget:self action:@selector(processButtonClick:) forControlEvents:UIControlEventTouchUpInside];
}

To add images in a thread I call a function which does following :

要在一个线程中添加图像,我调用了以下功能:

for(i = value; i < val; i++){
    UIImage *newimage = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL    URLWithString:[NSString stringWithFormat:@“http://test.com/a.jpg”, hash]]]];
    UIButton *newbutton = (UIButton*)[self.subviews objectAtIndex:i];
    [((UIImageView*)[newbutton.subviews objectAtIndex:0]) newimage];
}

3 个解决方案

#1


0  

Generally speaking, UIKit is not thread-safe. Fetch data from URL in a background thread and set the image in the main thread.

一般来说,UIKit不是线程安全的。在后台线程中从URL获取数据,并在主线程中设置图像。

EDIT: In your main thread do something like

编辑:在主线程中做一些类似的事情。

dispatch_async(someDispatchQ, ^{
    [self functionToGetData];
});

and inside functionToGetData do

和内部functionToGetData做

for(i = value; i < val; i++){
    NSData *data = //get Data
    UIImage *newImage = //make image from data
    dispatch_async(dispatch_get_main_queue(), ^{
        [imageView setImage:newImage];
    });
}

This will ensure that you are using a background thread to fetch data/make image and using the main thread to set the image. This also eliminates the need to use a timer to constantly poll the background thread since the background thread automatically dispatches image-setting to the main thread as soon as an image is received.

这将确保您使用后台线程来获取数据/生成图像,并使用主线程来设置图像。这也消除了使用计时器来持续轮询后台线程的需要,因为后台线程一旦接收到图像,就会自动将图像设置发送到主线程。

#2


0  

use- import class ImageDownloader.h & .m
link-> https://github.com/psychs/imagestore/tree/master/Classes/Libraries/ImageStore

ImageDownloader使用——导入类。h & .m link-> https://github.com/psychs/imagestore/tree/master/Classes/Libraries/ImageStore。

//Now use this method to download

//现在使用此方法下载。

-(void)downloadImageWithURL:(NSString *)url{


    if(self.downloder)return; //If already downloading please stay away

    url=[NSString stringWithFormat:@"%@%0.0fx%0.0f/%@/%@",IMAGE_ENDPOINT,self.imgViewExhibitors.frame.size.width,self.imgViewExhibitors.frame.size.height,@"fit",[ImagePath forURLString:url]];

    self.downloder=[[ImageDownloader alloc] init];
    self.downloder.delegate=self;
    self.downloder.indicator=self.indicator;
    [self.downloder downloadImageWithURL:url];
}

-(void)imageDownloaded:(UIImage *)image forIndexPath:(NSIndexPath *)indexPath{
    if(image){
        //Put the downloaded image in dictionary to update while scrolling
        //[self.speakerData setObject:image forKey:@"image"];
        self.imgViewExhibitors.image=image;
    }
}

#3


0  

A simple fix would be

一个简单的解决办法就是。

for(i = value; i < val; i++){
    UIImage *newimage = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL    URLWithString:[NSString stringWithFormat:@“http://test.com/a.jpg”, hash]]]];
    UIButton *newbutton = (UIButton*)[self.subviews objectAtIndex:i];

    // this ensures that the UI update (setting the image) is done on the main thread.
    // This is important for the UI to update properly.
    dispatch_async(dispatch_get_main_queue(), ^{
         [((UIImageView*)[newbutton.subviews objectAtIndex:0]) setImage:newimage];
    }
}

#1


0  

Generally speaking, UIKit is not thread-safe. Fetch data from URL in a background thread and set the image in the main thread.

一般来说,UIKit不是线程安全的。在后台线程中从URL获取数据,并在主线程中设置图像。

EDIT: In your main thread do something like

编辑:在主线程中做一些类似的事情。

dispatch_async(someDispatchQ, ^{
    [self functionToGetData];
});

and inside functionToGetData do

和内部functionToGetData做

for(i = value; i < val; i++){
    NSData *data = //get Data
    UIImage *newImage = //make image from data
    dispatch_async(dispatch_get_main_queue(), ^{
        [imageView setImage:newImage];
    });
}

This will ensure that you are using a background thread to fetch data/make image and using the main thread to set the image. This also eliminates the need to use a timer to constantly poll the background thread since the background thread automatically dispatches image-setting to the main thread as soon as an image is received.

这将确保您使用后台线程来获取数据/生成图像,并使用主线程来设置图像。这也消除了使用计时器来持续轮询后台线程的需要,因为后台线程一旦接收到图像,就会自动将图像设置发送到主线程。

#2


0  

use- import class ImageDownloader.h & .m
link-> https://github.com/psychs/imagestore/tree/master/Classes/Libraries/ImageStore

ImageDownloader使用——导入类。h & .m link-> https://github.com/psychs/imagestore/tree/master/Classes/Libraries/ImageStore。

//Now use this method to download

//现在使用此方法下载。

-(void)downloadImageWithURL:(NSString *)url{


    if(self.downloder)return; //If already downloading please stay away

    url=[NSString stringWithFormat:@"%@%0.0fx%0.0f/%@/%@",IMAGE_ENDPOINT,self.imgViewExhibitors.frame.size.width,self.imgViewExhibitors.frame.size.height,@"fit",[ImagePath forURLString:url]];

    self.downloder=[[ImageDownloader alloc] init];
    self.downloder.delegate=self;
    self.downloder.indicator=self.indicator;
    [self.downloder downloadImageWithURL:url];
}

-(void)imageDownloaded:(UIImage *)image forIndexPath:(NSIndexPath *)indexPath{
    if(image){
        //Put the downloaded image in dictionary to update while scrolling
        //[self.speakerData setObject:image forKey:@"image"];
        self.imgViewExhibitors.image=image;
    }
}

#3


0  

A simple fix would be

一个简单的解决办法就是。

for(i = value; i < val; i++){
    UIImage *newimage = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL    URLWithString:[NSString stringWithFormat:@“http://test.com/a.jpg”, hash]]]];
    UIButton *newbutton = (UIButton*)[self.subviews objectAtIndex:i];

    // this ensures that the UI update (setting the image) is done on the main thread.
    // This is important for the UI to update properly.
    dispatch_async(dispatch_get_main_queue(), ^{
         [((UIImageView*)[newbutton.subviews objectAtIndex:0]) setImage:newimage];
    }
}