开发者

how to increase the performance of loading an image from url

i m loading an image from an url and displaying it in imageView .i m using NSBLockOperation to load the image and it runs in the background and it takes time to load the image in imageview..is there any way to increase the performance so that it takes less time..below is the code.

NSOperationQueue *queue=[[NSOperationQueue alloc]init];
NSBlockOperation *operation=[NSBlockOperation blockOperationWithBlock:^{

    [activityIndicator startAnimating];
    NSString *imagefile = [banner1 objectAtIndex:0]; 
    NSURL *url1=[NSURL URLWithString:imagefile];
    NSData *data = [NSData dataWithContentsOfURL:url1];
    UIImage *ui=[[UIImage alloc]initWithData:data];
    bigbanner.image=ui;
    [activityIndicator stopAnimating];
    bigbanner.alpha=0.0;

}];
[operation setCompletionBlock:^{
    [UIView animateWithDuration:3.0 animations:^{bigbanner.alpha=2.0;}
                     completion:^(BOOL finished){}];
}];

[queue addOperation:operation];
开发者_如何学编程

how to increase the performance of loading an image from url


I would guess that your limiting factor is the image download. Loading an image and placing it on screen happens quite fast on iOS.

Other than changing your three second fade-in to a shorter interval, I think you're stuck.

You might try doing the download using [NSURLRequest], but I doubt you'll notice a major difference.

I'd say your options are (ranked in order of speed):

  1. cache or include images in your bundle (don't download).
  2. make your images smaller
  3. increase the speed of your server

Also: a side note, and hopefully someone else passing through can answer this... is setting the image property of a UIImageView from a non-main-thread safe to do? I was under the impression that everything that happened to the UI was supposed to happen on the main thread.


Give ASIHTTPRequest a try, just maybe loading image asynchrony in the background can improve speed when loading several images at the same time, checkout ASINetworkQueue

Didn't try it but here it is:

#import "ASIHTTPRequest.h"
#import "ASINetworkQueue.h"

-(void)loadImages
{
    ASINetworkQueue * asiNetworkQueue = [ASINetworkQueue queue];
    [asiNetworkQueue setDelegate:self];
    [asiNetworkQueue setShouldCancelAllRequestsOnFailure:NO];

    for(int i=0; i < 20; i++)
    {
        NSURL *url = [NSURL URLWithString:@"some_url"];

        ASIHTTPRequest *request = [[[ASIHTTPRequest alloc] initWithURL:url] autorelease];
        [request setDidFinishSelector:@selector(imageRequestFinished:)];
        [request setUserInfo:[NSDictionary dictionaryWithObject:[NSNumber numberWithInt:i] forKey:@"id"]];
    }
    [asiNetworkQueue go];
}

-(void)imageRequestFinished:(ASIHTTPRequest *)request
{

    UIImage* image = [UIImage imageWithData:[request responseData]];

    //Use the id to match the request with a specific UIImageView
    int imageId = [request.userInfo objectForKey:@"id"];
    //imageViewArray[imageId].image = image;
}

//------------------------------------ EDIT - Loading a single image //------------------------------------

-(void)loadImage:(NSString*)imagePath
{
    //_activityIndicator.hidden = FALSE;
    //[_activityIndicator startAnimating];
    NSURL*imageURL = [NSURL URLWithString:imagePath];

    ASIHTTPRequest* request = [[[ASIHTTPRequest alloc] initWithURL:imageURL] autorelease];

    [request setDidFailSelector:@selector(requestDidFailed:)];
    [request setDidStartSelector:@selector(requestDidStarted:)];
    [request setDidFinishSelector:@selector(requestDidFinished:)];
    [request setDelegate:self];
    [request startAsynchronous]; 

}

- (void)requestDidFinished:(ASIHTTPRequest *)request
{
    //_activityIndicator.hidden = TRUE;
    //[_activityIndicator stopAnimating];
    self.imageView.image = [UIImage imageWithData:[request responseData]];

    // NSLog(@"image download finished");
}

- (void)requestDidFailed:(ASIHTTPRequest *)request
{
    NSError *error = [request error];
    //NSLog(@"Loading Image Failed");
    //_activityIndicator.hidden = TRUE;
    //[_activityIndicator stopAnimating];
}

- (void)requestDidStarted:(ASIHTTPRequest *)request
{
    //NSLog(@"image download started");
}


As others have mentioned there's not much that you can do if the limiting resource is network speed. If the files aren't too large (and they don't look to be) you could preload them before the user reaches the page. For example, if there's only a few banners you could start loading all of them right when the app starts. If there's too many to do that you could try making educated guesses - e.g. If the user lands on a screen that can only lead him to 4 possible banners start downloading them all when the user lands on that screen in preparation for when they make their selection. Finally you should cache the banners once downloaded so you only have to pay for the network access once.

Hope that helps.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜