欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  移动技术

ios通过按钮点击异步加载图片

程序员文章站 2022-06-09 19:45:26
比较原始的方法: 复制代码 代码如下: asyncimageview.h: #import @interface asy...

比较原始的方法:

复制代码 代码如下:

asyncimageview.h:
#import <uikit/uikit.h>
@interface asyncimageview : uiview
{
    nsurlconnection* connection;
    nsmutabledata* data;
}
- (void)loadimagefromurl:(nsurl*)url;
@end
asyncimageview.m:
#import "asyncimageview.h"
@implementation asyncimageview
- (id)initwithframe:(cgrect)frame
{
    self = [super initwithframe:frame];
    if(self) {
        // initialization code
    }
    returnself;
}
- (void)loadimagefromurl:(nsurl*)url {
    if(connection!=nil) { [connection release]; }
    if(data!=nil) { [data release]; }
    nsurlrequest* request = [nsurlrequest requestwithurl:url
                                             cachepolicy:nsurlrequestuseprotocolcachepolicy
                                         timeoutinterval:60.0];
    connection = [[nsurlconnection alloc]
                  initwithrequest:request delegate:self];
}
- (void)connection:(nsurlconnection *)theconnection
    didreceivedata:(nsdata *)incrementaldata {
    if(data==nil) {
        data =
        [[nsmutabledata alloc] initwithcapacity:2048];
    }
    [data appenddata:incrementaldata];
}
- (void)connectiondidfinishloading:(nsurlconnection*)theconnection {
    [connection release];
    connection=nil;
    if([[self subviews] count] > 0) {
        [[[self subviews] objectatindex:0] removefromsuperview];
    }
    uiimageview *imageview = [[[uiimageview alloc] initwithimage:[uiimage imagewithdata:data]] autorelease];
    imageview.contentmode = uiviewcontentmodescaleaspectfit;
    imageview.autoresizingmask = ( uiviewautoresizingflexiblewidth | uiviewautoresizingflexibleheight );
    [self addsubview:imageview];
    imageview.frame = self.bounds;
    [imageview setneedslayout];
    [self setneedslayout];
    [data release];
    data=nil;
}
- (uiimage*) image {
    uiimageview* iv = [[self subviews] objectatindex:0];
    return[iv image];
}
- (void)dealloc {
    [connection cancel];
    [connection release];
    [data release];
    [super dealloc];
}
@end

方法二:

复制代码 代码如下:

@interface uibutton (asyncimage)
//size by point
- (void)setimagefromurl:(nsstring *)urlstring adjusttosize:(cgsize)size completion:(void (^)(void))completion logo:(uiimage *)logoimage;
@end
@implementation uibutton (asyncimage)
- (void)setimagefromurl:(nsstring *)urlstring adjusttosize:(cgsize)size completion:(void (^)(void))completion logo:(uiimage *)logoimage
{
    dispatch_async(dispatch_get_global_queue(dispatch_queue_priority_default, 0), ^{
        uiimage *image = nil;
        nsurl *url = [nsurl urlwithstring:urlstring];
        nsdata *data = [nsdata datawithcontentsofurl:url];
        image = [uiimage imagewithdata:data];   
        if (image) {
            if (!cgsizeequaltosize(size, cgsizezero)) {
                image = [uiimage imagewithcgimage:image.cgimage scale:[self scaleimage:image adjusttosize:size] orientation:image.imageorientation];
            }
            if (logoimage) {
                image = [self addlogoimage:logoimage toimage:image];
            }
            dispatch_async(dispatch_get_main_queue(), ^{
                [self setimage:image forstate:uicontrolstatenormal];
                completion();
            });
        }
        else {
            nslog(@"async load error.");
        }
    });
}
// 缩放图片以适应按钮大小
- (cgfloat)scaleimage:(uiimage *)image adjusttosize:(cgsize)size
{
    cgfloat xscale = size.width / image.size.width;
    cgfloat yscale = size.height / image.size.height;
    return 1.0 / min(xscale, yscale);
}
- (uiimage *)addlogoimage:(uiimage *)logo toimage:(uiimage *)img
{
    //get image width and height
    cgfloat scale = [uiscreen mainscreen].scale;
    int w = scale * img.size.width;
    int h = scale * img.size.height;
    int logowidth = logo.scale * logo.size.width;
    int logoheight = logo.scale * logo.size.height;
    cgcolorspaceref colorspace = cgcolorspacecreatedevicergb();
    //create a graphic context with cgbitmapcontextcreate
    cgcontextref context = cgbitmapcontextcreate(null, w, h, 8, 4 * w, colorspace, kcgimagealphapremultipliedfirst);
    cgcontextdrawimage(context, cgrectmake(0, 0, w, h), img.cgimage);
    cgcontextdrawimage(context, cgrectmake(w - logowidth, 0, logowidth, logoheight), [logo cgimage]);
    cgimageref imagemasked = cgbitmapcontextcreateimage(context);
    cgcontextrelease(context);
    cgcolorspacerelease(colorspace);
    return [uiimage imagewithcgimage:imagemasked scale:scale orientation:img.imageorientation];
}
@end

方法三:

#import <foundation/foundation.h>
#import "stringutils.h"

@interface imagemanager : nsobject
{
  nsmutabledictionary *_imagedict;
  nsmutablearray *_imagearr;
}

@property(nonatomic, strong) nsstring *httpurl;
@property(nonatomic, strong) nsmutabledictionary *imagedict;

@property(nonatomic, assign) dispatch_queue_t networkqueue;

+ (imagemanager *) sharedinstance;


- (void)asyncimage:(nsstring *)imagename imageview:(uiimageview *)imageview;
//插队
- (void)asyncimageinsert:(nsstring *)imagename imageview:(uiimageview *)imageview insert:(bool)insert;
//不要在下载之前的数据
- (void)asyncimagecleanold:(nsstring *)imagename imageview:(uiimageview *)imageview cleanold:(bool)cleanold;

@end

实现文件:

//
// imagemanager.m
// myb-ios
//
// created by warrior gao on 13-6-5.
// copyright (c) 2013年 51myb. all rights reserved.
//

#import "imagemanager.h"

@interface imagemanager()

@end

@implementation imagemanager

//缓存图片的最大数量
static int counter = 0;

@synthesize imagedict = _imagedict;

//singleton 
+ (imagemanager *)sharedinstance
{
  static id instance;
  static dispatch_once_t oncetoken;
  dispatch_once(&oncetoken, ^{
    instance = self.new;
  });
  return instance;
}

- (id)init
{
  if((self = [super init]))
  {
    self.networkqueue = dispatch_queue_create("com.warrior.network.image", nil);
    _imagedict = [[nsmutabledictionary alloc] init];
    _imagearr = [[nsmutablearray alloc] init];
  }
  return self;
}

- (nsstring *) filefullpath:(nsstring *)filename
{
  nsstring *cachepath = [nssearchpathfordirectoriesindomains(nscachesdirectory, nsuserdomainmask, yes) objectatindex:0];
  
  nsstring *filefullpath = [nsstring stringwithformat:@"%@/%@",cachepath,filename];
  
  return filefullpath;
}

//不要在下载之前的数据
- (void)asyncimagecleanold:(nsstring *)imagename imageview:(uiimageview *)imageview cleanold:(bool)cleanold
{
  if(cleanold)
  {
    [_imagearr removeallobjects];
  }
  
  [self asyncimage:imagename imageview:imageview];
}

//插队,优先
- (void)asyncimageinsert:(nsstring *)imagename imageview:(uiimageview *)imageview insert:(bool)insert
{
  if([stringutils isempty:imagename]){
    return;
  }
  
  nsdata *data = [nsdata datawithcontentsoffile:[self filefullpath:[imagename stringbyreplacingoccurrencesofstring:@"/" withstring:@"-"]]];
  if(data == nil){
    [_imagedict setvalue:imageview forkey:imagename];
    if(insert)
    {
      [_imagearr insertobject:imagename atindex:0];
    }
    else
    {
      [_imagearr addobject:imagename];
    }
    
    [self cacheimage];
  } else {
    [imageview setimage:[uiimage imagewithdata:data]];
  }
}

//正常,附加到后面
- (void)asyncimage:(nsstring *)imagename imageview:(uiimageview *)imageview
{
  [self asyncimageinsert:imagename imageview:imageview insert:no];
}

//异步缓存图片到本地,最多有两个线程
-(void)cacheimage
{
  for (; counter < 2 && _imagearr.count > 0; counter++)
  {
    nsstring *imagename = nil;
    @synchronized(self){
      imagename = [[_imagearr objectatindex:0] copy];
      [_imagearr removeobjectatindex:0];
    }
    
    if(imagename == nil) continue;
    
    dispatch_async(self.networkqueue, ^{
      
      nslog(@"starting: %@", imagename);
      uiimage *avatarimage = nil;
      nsurl *url = [nsurl urlwithstring:[nsstring stringwithformat:@"%@%@",self.httpurl, imagename]];
      nsdata *responsedata = [nsdata datawithcontentsofurl:url];
      if(responsedata.length > 0)
      {
        [responsedata writetofile:[self filefullpath:[imagename stringbyreplacingoccurrencesofstring:@"/" withstring:@"-"]] atomically:no];
        avatarimage = [uiimage imagewithdata:responsedata];
        nslog(@"finishing: %@", imagename);
        
        if (avatarimage) {
          dispatch_async(dispatch_get_main_queue(), ^{
            uiimageview *imageview = [_imagedict objectforkey:imagename];
            if(imageview != nil && avatarimage != nil){
              [imageview setimage:avatarimage];
            }
            
            [_imagedict removeobjectforkey:imagename];
            [imagename release];
          });
        }
      }
      counter--;
      [self cacheimage];
    });
    
  }
}

@end

以上所述就是本文的全部内容 了,希望大家能够喜欢。