Loading images in background to optimize the loading in ios

后端 未结 9 1253
星月不相逢
星月不相逢 2021-02-02 03:02

I am trying to optimize the load in my application, in fact, I have a lot of images that loaded in my application, and I spend a lot of time waiting for a view controller to ope

相关标签:
9条回答
  • 2021-02-02 03:24

    You can try something like this!....

     dispatch_queue_t checkInQueueForPostImage = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
    
                            dispatch_async(checkInQueueForPostImage, ^{
                                UIImage *image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:postAndCheckInDetails.postImageURL]]];
    
                                dispatch_sync(dispatch_get_main_queue(), ^{
                                    if (image!=nil) {
                                        [uploadImage setImage:image];
                                    }
    
                                    [cell setNeedsLayout];
                                });
                            });
    
    0 讨论(0)
  • To enable the app while getting the images from server and disable block while loading the images try to use UIImageView+AFNetworking library to load the image from server asynchronously AFNetworking

       NSString *imageUrl = [[dict objectForKey:@"photo"] objectForKey:@"url"];
    
       UIImageView *myImage = [[UIImageView alloc] init];
    
       [myImage setImageWithURL:[NSURL URLWithString:imageUrl] placeholderImage:[UIImage    imageNamed:@"PlaceHolder.png"]];
    

    Just add this library and include the UIImageView+AFNetworking so you can use the new UIImageView Category imageWithUrl

    0 讨论(0)
  • 2021-02-02 03:25

    you can check this tutorial on NSOperationQueue and this on GCD doing exactly same. Also you can try using:

    // Block variable to be assigned in block.
    __block NSData *imageData;
    dispatch_queue_t backgroundQueue  = dispatch_queue_create("com.razeware.imagegrabber.bgqueue", NULL);
    
    // Dispatch a background thread for download
    dispatch_async(backgroundQueue, ^(void) {
        imageData = [NSData dataWithContentsOfURL:imageURL];
        UIImage *imageLoad;
        imageLoad = [[UIImage alloc] initWithData:imageData];
    
        // Update UI on main thread
        dispatch_async(dispatch_get_main_queue(), ^(void) {
            imageView.image = imageLoad;
        });
    });
    
    0 讨论(0)
  • 2021-02-02 03:31

    Use IDAsyncImageView.h

     //////////////////////////////////////
        IDAsyncImageView.h
     /////////////////////////////////////
    
            @interface IDAsyncImageView : NSObject
    
            @property (nonatomic, strong) NSCache *cache;    
    
            + (instancetype)instance;
    
            - (void)loadImageView:(UIImageView*)imageView withURLString:(NSString *)urlString;
    
            @end
    
        //////////////////////////////////////
        IDAsyncImageView.m
        /////////////////////////////////////
    
            #import "IDAsyncImageView.h"
    
    
    
                @implementation IDAsyncImageView
    
                    + (instancetype)instance
                    {
                        static IDAsyncImageView *_instance = nil;
                        static dispatch_once_t onceToken;
                        dispatch_once(&onceToken, ^{
                            _instance = [[self alloc] init];
                    });
                    return _instance;
                }
    
            - (instancetype)init
            {
                self = [super init];
                if (self) {
                    self.cache =  [[NSCache alloc] init];
                }
    
                return self;
            }
    
            - (void)loadImageView:(UIImageView*)imageView withURLString:(NSString *)urlString
            {
                UIActivityIndicatorView* activityView;
                activityView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleGray];
                activityView.hidesWhenStopped = YES;
                activityView.center = CGPointMake(imageView.bounds.size.width / 2.0f, imageView.bounds.size.height / 2.0f);
                activityView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleBottomMargin;
                [imageView addSubview:activityView];
                [activityView startAnimating];
    
                UIImage* imageLoad = [self.cache objectForKey:urlString];
                if (nil != imageLoad) {
                    imageView.image = imageLoad;
                    [activityView removeFromSuperview];
                }
                else {
    
                // Block variable to be assigned in block.
                __block NSData *imageData;
    
                // Dispatch a background thread for download
                dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_BACKGROUND, 0), ^{
                    imageData = [NSData dataWithContentsOfURL:[NSURL URLWithString:urlString]];
                    UIImage* imageLoad = [[UIImage alloc] initWithData:imageData];
    
                    // Update UI on main thread
                    dispatch_async(dispatch_get_main_queue(), ^(void) {
                        [self.cache setObject:imageLoad forKey:urlString];
                        imageView.image = imageLoad;
                        [activityView removeFromSuperview];
                    });
                });
                }
            }
    
        //////////////////////////////////////
        ViewController.m
        //////////////////////////////////////
    
            - (void)viewDidLoad {
            [super viewDidLoad];
            [[IDAsyncImageView instance] loadImageView:myImageView withURLString:aUrl];
            }
    
    0 讨论(0)
  • 2021-02-02 03:36

    Take a look at this control: https://github.com/nicklockwood/AsyncImageView

    It's very easy to implement (only 1 header file) and will suit your needs just fine.

    Using this control: Instead of declaring:

    NSURL *imageURL = ......;
    NSData *imageData = [NSData dataWithContentsOfURL:imageURL];
    UIImage *imageLoad;
    imageLoad = [[UIImage alloc] initWithData:imageData];
    imageView.image = imageLoad;
    

    Use:

    NSURL *imageURL = ......;
    imageView.imageURL = imageURL;
    
    0 讨论(0)
  • 2021-02-02 03:41

    Try this code:

    dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
    dispatch_async(q, ^{
        /* Fetch the image from the server... */
        NSData *data = [NSData dataWithContentsOfURL:url];
        UIImage *img = [[UIImage alloc] initWithData:data];
        dispatch_async(dispatch_get_main_queue(), ^{
            /* This is the main thread again, where we set the tableView's image to
             be what we just fetched. */
            cell.imgview.image = img;
        });
    });
    
    0 讨论(0)
提交回复
热议问题