Загрузка изображений в фоновом режиме для оптимизации загрузки в iOS

Я пытаюсь оптимизировать нагрузку в моем приложении, на самом деле, у меня есть много изображений, загруженных в моем приложении, и я провожу много времени в ожидании открытия контроллера вида, особенно первого начального вида, который включает в себя много изображений.

Я взглянул на образец яблока

но я не могу повторно работать все приложение, что я хочу, это просто сказать мне конкретно, что я должен делать?- Я реализую?

на tableview, где ячейка реализована cellforrowatindexpath:

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

могу я что-нибудь сделать?

спасибо за вашу помощь!

enter image description here

9 ответов


Да, вы можете добавить местозаполнитель изображение к нему.

он не замедлит прокрутку и будет загружать изображение соответственно со временем.

и импорт этот файл UIImageView + WebCache.м и MapKit с рамки

вот ссылка для загрузки файлов.

- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
     static NSString *CellIdentifier = @"Cell";
        UITableViewCell *cell = [tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) {
            cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleSubtitle reuseIdentifier:CellIdentifier];
        }
    UIImageview*  iV = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, 50, 50)];
   [iV setImageWithURL:[NSURL URLWithString:url] placeholderImage:[UIImage imageNamed:@"image_placeholder.gif"]];
   [cell.contentView addSubview:iV];
   [iV release];

}

просто очистить, собрать и запустить.


попробуйте этот код:

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;
    });
});

включить приложения при получении изображений с сервера и отключить блок при загрузке изображения, попробуйте использовать UIImageView+AFNetworking библиотека для асинхронной загрузки изображения с сервера AFNetworking

   NSString *imageUrl = [[dict objectForKey:@"photo"] objectForKey:@"url"];

   UIImageView *myImage = [[UIImageView alloc] init];

   [myImage setImageWithURL:[NSURL URLWithString:imageUrl] placeholderImage:[UIImage    imageNamed:@"PlaceHolder.png"]];

просто добавьте эту библиотеку и включите UIImageView+AFNetworking, чтобы вы могли использовать новую категорию UIImageView imageWithUrl


взгляните на этот элемент управления: https://github.com/nicklockwood/AsyncImageView

это очень легко реализовать (только 1 файл заголовка) и будет соответствовать вашим потребностям просто отлично.

использование этого элемента управления: Вместо объявления:

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

использование:

NSURL *imageURL = ......;
imageView.imageURL = imageURL;

вы можете проверить этот учебник о NSOperationQueue и это GCD делает то же самое. Также вы можете попробовать использовать:

// 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;
    });
});

вы можете попробовать что-то вроде этого!....

 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];
                            });
                        });

вот слегка измененный подход ответа раму Пасуполетиса. Я добавил __блок модификатор, чтобы сделать var img видимым внутри блока, вызываемого в основном потоке. Вот полное определение метода, которое я использую в

-(UITableViewCell*)cellforRowAtIndexPath:(UIIndexPath*)indexPath;

для ленивого извлечения эскизов. Я также добавил туда заполнители для ячеек UIImageViews.

//lazy loading of thumbnails for images in cell via bg thread
-(void)loadImageForCell:(CustomEditTableViewCell*)theCell withFilepath: (NSString*)filepath{

dispatch_queue_t q = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
dispatch_async(q, ^{
    UIImage (__block *img) = [UIImage imageWithContentsOfFile:filepath];
    UIImage *thumbnail = [[GlobalFunctions sharedGlobalFunctions] imageOfSize:CGSizeMake(40, 40) fromImage:img];
    dispatch_async(dispatch_get_main_queue(), ^{
        theCell.imageView.image = thumbnail;
    });
});
}

Используйте 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];
        }

вы можете использовать async imageview.

- (void) loadImageFromURL:(NSURL*)url placeholderImage:(UIImage*)placeholder cachingKey:(NSString*)key {
    self.imageURL = url;
    self.image = placeholder;

    NSData *cachedData = [FTWCache objectForKey:key];
    if (cachedData) {   
       self.imageURL   = nil;
       self.image      = [UIImage imageWithData:cachedData];
       return;
    }

    dispatch_queue_t queue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_HIGH, 0ul);
    dispatch_async(queue, ^{
        NSData *data = [NSData dataWithContentsOfURL:url];

        UIImage *imageFromData = [UIImage imageWithData:data];

        [FTWCache setObject:data forKey:key];

        if (imageFromData) {
            if ([self.imageURL.absoluteString isEqualToString:url.absoluteString]) {
                dispatch_sync(dispatch_get_main_queue(), ^{
                    self.image = imageFromData;
                });
            } else {
//              NSLog(@"urls are not the same, bailing out!");
            }
        }
        self.imageURL = nil;
    });
}

посмотри этой ссылке.У вас будет идея по использованию async imageview.