2012-03-19 2 views
4

Мне нужно загрузить изображение из Интернета и отобразить его в ImageView. В настоящее время я использую SDWebImage (это асинхронный загрузчик изображений с поддержкой кеша, с категорией UIImageView).Скачать изображение асинхронно

Но он падает, когда я нажимаю кнопку «Назад» и кнопку «вперед» (когда я пытаюсь снова и снова переходить в режим просмотра). В любом случае это случается очень редко, но мне нужно избавиться от этой ошибки. Есть ли другая библиотека (которая не использует частный API), которую я мог бы использовать в моем проекте?

+0

пожалуйста отправьте свой журнал сбоев, если это возможно. –

+0

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

+0

Если проблема еще не решена. Использование JImage.h и JImage.m поможет вам в любом состоянии, которое я опубликовал, вам просто нужно скопировать и вставить, что будет работать автоматически. Это очень эффективные классы, которые я реализовал и работал очень хорошо для меня при ленивой загрузке изображений (загрузка async) – Kuldeep

ответ

10

Да. Вы можете использовать другую библиотеку. Я уже реализовал это с использованием AsyncImageView, который унаследован от UIImageView. То, что он делает, это сохранение изображений в памяти Cache, извлеченных из URL-адреса, и всякий раз, когда вам нужно загрузить изображение с , тот же самый адрес, он просто загрузит его из кэш-памяти, экономя много времени.

Просто следуйте по ссылке для реализации, что:

https://github.com/nicklockwood/AsyncImageView#readme

http://www.markj.net/iphone-asynchronous-table-image/

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

enter image description here

+0

делает 'AsyncImageView' или' iphone-asynchronous-table-image' использование какого-либо частного API? вы сталкивались с этим? – shajem

+0

https://github.com/nicklockwood/AsyncImageView/blob/master/LICENCE.md –

+1

Это не говорит, если он использует частные API или нет – shajem

6

NSURLConnection обеспечивает асинхронную загрузку и встроен в iOS.

+0

Является ли это лучшим подходом, чем «SDWebImage», как в нем есть поддержка кеша? – shajem

+0

сохраняет данные в памяти. зависит от того, как вы справляетесь с данными. – Bahamut

+1

Не возражайте, но предлагая альтернативное решение, которое требует повторного восстановления усилий, не является правильным способом ответа на вопросы. Теперь поместите себя на свое место и подумайте, нужно ли вам перестроить все свои вещи, что вы будете делать? Мы должны посмотреть журнал аварий и помочь ему оттуда –

4

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

Другая альтернатива для загрузки изображений async - http://allseeing-i.com/ASIHTTPRequest/.

+0

ASIHTTPRequest больше не является хорошей альтернативой. Еще в те дни, когда встроенные классы были слишком слабыми, было приятно использовать, но теперь, когда NSURLConnection выросла, _and_ разработка для ASIHTTPRequest была остановлена, это не лучший путь. – Ahti

0

Я лично предпочитаю использовать NSURLConnection sendSynchronousRequest и помещать вокруг него обертку GCD. Сохраняет все аккуратное и аккуратное.

2
//JImage.h 

#import <Foundation/Foundation.h> 


@interface JImage : UIImageView { 

    NSURLConnection *connection; 

    NSMutableData* data; 

    UIActivityIndicatorView *ai; 
} 

-(void)initWithImageAtURL:(NSURL*)url; 

@property (nonatomic, retain) NSURLConnection *connection; 

@property (nonatomic, retain) NSMutableData* data; 

@property (nonatomic, retain) UIActivityIndicatorView *ai; 

@end 



//JImage.m 

#import "JImage.h" 

@implementation JImage 
@synthesize ai,connection, data; 

-(void)initWithImageAtURL:(NSURL*)url { 


    [UIApplication sharedApplication].networkActivityIndicatorVisible = YES; 

    [self setContentMode:UIViewContentModeScaleToFill]; 

    if (!ai){ 

     [self setAi:[[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge]]; 

     [ai startAnimating]; 

     [ai setFrame:CGRectMake(27.5, 27.5, 20, 20)]; 

     [ai setColor:[UIColor blackColor]]; 

     [self addSubview:ai]; 
    } 
    NSURLRequest* request = [NSURLRequest requestWithURL:url cachePolicy:NSURLRequestUseProtocolCachePolicy timeoutInterval:60]; 

    connection = [[NSURLConnection alloc] initWithRequest:request delegate:self];  
} 


- (void)connection:(NSURLConnection *)theConnection didReceiveData:(NSData *)incrementalData { 

if (data==nil) data = [[NSMutableData alloc] initWithCapacity:5000]; 

[data appendData:incrementalData]; 

NSNumber *resourceLength = [NSNumber numberWithUnsignedInteger:[data length]]; 

NSLog(@"resourceData length: %d", [resourceLength intValue]); 

} 
- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error 
{ 
    NSLog(@"Connection error..."); 

    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; 

    [ai removeFromSuperview]; 

} 
- (void)connectionDidFinishLoading:(NSURLConnection*)theConnection 
{ 
    [UIApplication sharedApplication].networkActivityIndicatorVisible = NO; 

    [self setImage:[UIImage imageWithData: data]]; 

    [ai removeFromSuperview]; 
} 
@end 



//Include the definition in your class where you want to use the image 
-(UIImageView*)downloadImage:(NSURL*)url:(CGRect)frame { 

JImage *photoImage=[[JImage alloc] init]; 

    photoImage.backgroundColor = [UIColor clearColor]; 

    [photoImage setFrame:frame]; 

    [photoImage setContentMode:UIViewContentModeScaleToFill]; 

    [photoImage initWithImageAtURL:url]; 

    return photoImage; 
} 


//How to call the class 

UIImageView *imagV=[self downloadImage:url :rect]; 

//you can call the downloadImage function in looping statement and subview the returned imageview. 
//it will help you in lazy loading of images. 


//Hope this will help 
2

Ознакомиться с EGOImageLoading от пользователя для получения кеширования изображений. Это работает как UIImageView и позволяет загружать изображения из HTTP асинхронно, а также легко интегрируется

+0

Использует ли он какие-либо частные API? – shajem

+0

Нет, он не использует какие-либо частные API-интерфейсы –

4

Я лично использую встроенную функцию Grand Central Dispatch в iOS для асинхронного скачивания изображений с сервера.

Ниже приведен код, который я использовал для загрузки фотографий с Flickr в одном из моих приложений.

В вашем изображение/фото класс, есть функция, которая является чем-то вроде этого:

- (void)processImageDataWithBlock:(void (^)(NSData *imageData))processImage 
{ 
NSString *url = self.imageURL; 
dispatch_queue_t callerQueue = dispatch_get_current_queue(); 
dispatch_queue_t downloadQueue = dispatch_queue_create("Photo Downloader", NULL); 
dispatch_async(downloadQueue, ^{ 
    NSData *imageData = *insert code that fetches photo from server*; 
    dispatch_async(callerQueue, ^{ 
     processImage(imageData); 
    }); 
}); 
dispatch_release(downloadQueue); 
} 

В вашем фото View Controller, вы можете вызвать эту функцию следующим образом:

- (void)viewWillAppear:(BOOL)animated 
{ 
[spinner startAnimating]; 
[self.photo processImageDataWithBlock:^(NSData *imageData) { 
    if (self.view.window) { 
     UIImage *image = [UIImage imageWithData:imageData]; 
     imageView.image = image; 
     imageView.frame = CGRectMake(0, 0, image.size.width, image.size.height); 
     scrollView.contentSize = image.size; 
     [spinner stopAnimating]; 
    } 
}]; 
} 
1

Я знаю, что это очень старая нить, но в последнее время у меня было много случайных аварии с SDWebImage, поэтому я должен был реализовать собственные ленивые загрузки и кэширование механизма. Он работает очень хорошо, я просто не тестировал его в случаях большой нагрузки. Так вот .h и .m файлы следуют по пути я использую его:

// UIImageView+CustomCache.h 
@interface UIImageView(CustomCache) 

-(void)startAsyncDownload:(UIImage*)placeHolderImage imageUrlString:(NSString*)imageUrlString; 
@end 


// UIImageView+CustomCache.m 

#import "UIImageView+CustomCache.h" 

@implementation UIImageView(CustomCache) 

-(void)startAsyncDownload:(UIImage*)placeHolderImage imageUrlString:(NSString*)imageUrlString{ 
    self.image = placeHolderImage; 
    [NSURLConnection sendAsynchronousRequest:[NSURLRequest requestWithURL: 
               [NSURL URLWithString:imageUrlString]] queue:[NSOperationQueue mainQueue] completionHandler:^(NSURLResponse *response, NSData *data, NSError *connectionHandler){ 
     @autoreleasepool { 
      if (connectionHandler != nil) { 
       NSLog(@"error in downloading description %@",connectionHandler.localizedDescription); 
      } else { 
       ImagesCacheHandler *ref = [ImagesCacheHandler new]; 
       UIImage *imageFromData = [[UIImage alloc] initWithData:data]; 
       if (imageFromData != NULL && imageFromData != nil && data.length > 0) { 
        self.image = imageFromData; 
//custom store to sqlite 
        [ref archiveImage:imageUrlString imageData:data moc:[ref fetchContext]]; 
       } 
      } 
     } 
    }]; 
} 

@end 

И в моем представлении таблицы я использую (я импорт конечно UIImageView + CustomCache.h)

UIImageView *imageViewToLazyLoad = (UIImageView*)[cell viewWithTag:1]; 
[imageViewToLazyLoad startAsyncDownload:[UIImage [email protected]"palce_Holder_Image_name"] imageUrlString:imageUrl]; 
Смежные вопросы