Завантаження зображень у фоновому режимі для оптимізації завантаження в ios

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

I took a look at apple sample

але я не можу переробити всю програму, я хочу просто сказати мені, що я повинен робити ?, я здійснюю?

in the tableview, where the cell is implemented cellforrowatindexpath:

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

чи можу я щось зробити?

Дякую за твою допомогу!

enter image description here

8
NSData * imageData = [NSData dataWithContentsOfURL: imageURL]; займе багато часу .. спробуйте асинхронне завантаження зображень
додано Автор Ramu Pasupuleti, джерело
Ви можете написати це як код? будь ласка, скажіть мені, як?
додано Автор CarinaM, джерело

9 Відповіді

Спробуйте цей код:

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;
    });
});
6
додано
Я спробував ваше рішення для перегляду зображень у проекті. Відмінно працює! Просто хотів додати його, а також для лінького завантаження ескізів в UITableViewCells і з'явилася невелика проблема: UIImage * img не відображається всередині блоку, який викликає основний потік. Дасть йому дослідження!
додано Автор Torsten Barthel, джерело
Я знайшов просте рішення, щоб видно вар у інших блогах в головній черзі. Я додам його як нову відповідь і розміщую мою відредагований фрагмент коду.
додано Автор Torsten Barthel, джерело
Я постараюся дати вам відгук
додано Автор CarinaM, джерело

Так, ви можете додати зображення до нього місцевому .

Це не призведе до сповільнення прокрутки та завантаження зображення відповідно до часу.

Також імпорту цього файлу UIImageView + WebCache.m та MapKit Framework

Here is the link to download the files.

- (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];

}

Just clean, build and run.

3
додано
Добре. Насолоджуйтесь кодуванням !!
додано Автор AtWork, джерело
Ohke .. Вам також потрібно імпортувати карту MapKit.
додано Автор AtWork, джерело
Звичайно .. Це обов'язково буде працювати.
додано Автор AtWork, джерело
Ви додали всі файли в проект xcode? Всі файли повинні з'явитися в лівій панелі xcode.
додано Автор AtWork, джерело
Додати повну папку у ваш проект і просто #import "UIImageView + WebCache.h" у файлі, в якому ви завантажуєте зображення в UITableview .
додано Автор AtWork, джерело
дивись, я дуже щаслива, і дуже дякую, він працює, ніж няннккккк твоємууууууу
додано Автор CarinaM, джерело
Я додав його, і я додаю структуру imageIO, тепер працює, все-таки мені доводиться перевіряти, чи проблема з завантаженням зображень вирішена чи ні
додано Автор CarinaM, джерело
Перевірте скріншот вище
додано Автор CarinaM, джерело
Так, у лівій панелі вже з'являються 29 файлів
додано Автор CarinaM, джерело
Чи повинен я сам створювати кожен файл ??? або існує спосіб імпортувати їх правильно?
додано Автор CarinaM, джерело
коли я намагаюся скопіювати всю папку, я перевіряю (скопіювати елементи в групи призначення, якщо це потрібно), але при запуску програми виникла помилка: SDWebImageDownloaderOperation.o "_OBJC_CLASS _ $ _ MKAnnotationView", з посиланням: l_OBJC _ $ _ CATEGORY_MKAnnotationView_ $ _WebCache у MKAnnotationView + WebCache.o ld: символи не знайдені для архітектури armv7 clang: помилка: команда linker не вдалася з кодом виходу 1 (використовуйте -v, щоб побачити виклик) .........
додано Автор CarinaM, джерело
добре, дозвольте мені спробувати це
додано Автор CarinaM, джерело
потрібно імпортувати безліч файлів не просто UIImageView + WebCache.m ????
додано Автор CarinaM, джерело
Гаразд, дякую, дайте мені завтра спробувати це, будь ласка
додано Автор CarinaM, джерело
Я постараюся дати вам відгук
додано Автор CarinaM, джерело

Take a look at this control: 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;
2
додано
Я постараюся дати вам відгук
додано Автор CarinaM, джерело

ви можете перевірити це керівництво на NSOperationQueue і це на < a href = "http://www.raywenderlich.com/4295/multithreading-and-grand-central-dispatch-on-ios-for-beginners-tutorial" rel = "nofollow"> 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;
    });
});
2
додано
Я постараюся дати вам відгук
додано Автор CarinaM, джерело

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

2
додано
коли я додаю бібліотеку, я перевіряю (копіювати елементи в групи призначення, якщо це потрібно), але коли я його запускаю, з'явилася помилка: команда linker не вдалася з кодом виходу 1 (використовуйте -v, щоб побачити виклик) ...... ... Чи повинен я сам створювати кожен файл із цієї бібліотеки? або існує спосіб імпортувати його в моє додаток?
додано Автор CarinaM, джерело
Я постараюся дати вам відгук
додано Автор CarinaM, джерело

Ви можете спробувати щось подібне! ....

 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
додано
Я постараюся дати вам відгук
додано Автор CarinaM, джерело

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

- (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.

0
додано
Я постараюся дати вам відгук
додано Автор CarinaM, джерело

Ось трохи модифікований підхід відповіді Раму Пасуполетіса. Я додав     __block модифікатор, щоб зробити 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;
    });
});
}
0
додано

Використовуйте 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
додано
IT KPI iOS
IT KPI iOS
74 учасників

Чат обсуждения IOS. - Оффтоп, флуд, оскорбления и вбросы здесь не приняты. - За нарушение - предупреждение или mute на неделю. - За спам и рекламу - ban. Все чаты IT KPI: https://t.me/itkpi/602

ios_jobs_ua
ios_jobs_ua
27 учасників

Mobile Dev Jobs UA
Mobile Dev Jobs UA
20 учасників

Публикуем вакансии и запросы на поиск работы по направлению iOS, Android, Xamarin, RN и т.д.