zoukankan      html  css  js  c++  java
  • 使用NSoperation 实现异步加载图片

    采用UITableView显示从网络上下载的图片,因为网络图片下载比较耗费时间,一般采用边显示文字,内容,后台下载图片,下载完成后刷新TableViewCell ,本文将演示如何通过自定的UITableViewCell,显示图片。

    1。定义ImageTableViewCell 

    @interface ImageTableViewCell : UITableViewCell {
        UILabel *txtLabel;
        UIImageView *imageView;
    }
    @property(nonatomic, retain)IBOutlet UILabel *txtLabel;
    @property(nonatomic, retain)IBOutlet UIImageView *imageView;

    - (void)setCell:(UIImage *)image text:(NSString *)text;

    @end 

    方法添加如下 

     - (void)setCell:(UIImage *)image text:(NSString *)text

    {
        if (image != nil)
        {
            self.imageView.image = image;
        }
        
        self.txtLabel.text = text;

    }

     具体实现代码,请在源代码里查看

    2。定义ImageDownloader ,这个类继承NSOperation,因为需要并发,所以需要实现下面4个方法 

    //是否允许并发,
    -(BOOL)isConcurrent 
    - (BOOL)isExecuting
    //是否已经完成,这个必须要重载,不然放在放在NSOperationQueue里的NSOpertaion不能正常释放。
    - (BOOL)isFinished
    //具体下载的方法在这里执行。

    - (void)start 

    而对应于非并发的情况下,只需要重载main方法就好了。
    #import <Foundation/Foundation.h>

    @protocol imageDownloaderDelegate;

    @interface ImageDownloader : NSOperation 
    {
        NSURLRequest* _request;
        
        NSURLConnection* _connection;
        
        NSMutableData* _data;
        
        BOOL _isFinished; 
        
        id<imageDownloaderDelegate> delegate;
        
        NSObject *delPara;
    }

    - (id)initWithURLString:(NSString *)url;

    @property (readonly) NSData *data;
    @property(nonatomic, assign) id<imageDownloaderDelegate> delegate;
    @property(nonatomic, retain) NSObject *delPara;

    @end

    @protocol imageDownloaderDelegate

    @optional

    //图片下载完成的委托
    - (void)imageDidFinished:(UIImage *)image para:(NSObject *)obj;

    @end

     实现文件如下

     #import "ImageDownloader.h"

    @implementation ImageDownloader

    @synthesize data=_data;
    @synthesize delegate;
    @synthesize delPara;

    - (void)dealloc 
    {
        
        [_request release]; 
        _request=nil;
        
        [_data release];
        _data=nil;
        
        [_connection release];
        _connection=nil;
        
        [delPara release];
        
        [super dealloc];
        
    }
    - (id)initWithURLString:(NSString *)url 
    {
        
        self = [self init];
        if (self) {

            _request = [[NSURLRequest alloc] initWithURL:[NSURL URLWithString:url]];
            
            _data = [[NSMutableData data] retain];
            
        }
        
        return self;
        
    }



    // 开始处理-本类的主方法

    - (void)start {
        
        if (![self isCancelled]) {
            
            [NSThread sleepForTimeInterval:3];
            // 以异步方式处理事件,并设置代理
            
            _connection=[[NSURLConnection connectionWithRequest:_request delegate:self]retain];
            
            while(_connection != nil) {
                
                [[NSRunLoop currentRunLoop] runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];   
                
            }
            
        }
        
    }

    #pragma mark NSURLConnection delegate Method

    // 接收到数据(增量)时

    - (void)connection:(NSURLConnection*)connection

        didReceiveData:(NSData*)data 
    {
        // 添加数据
        [_data appendData:data];
        
    }

    - (void)connectionDidFinishLoading:(NSURLConnection*)connection {
        
        [_connection release],
        _connection=nil;
        NSLog(@"%s", __func__);
        
        UIImage *img = [[[UIImage alloc] initWithData:self.data] autorelease];
        
        if (self.delegate != nil)
        {
            [delegate imageDidFinished:img para:self.delPara];
        }
        
        
    }

    -(void)connection: (NSURLConnection *) connection didFailWithError: (NSError *) error
    {
        [_connection release],
        _connection=nil; 
    }

    -(BOOL)isConcurrent 
    {
        //返回yes表示支持异步调用,否则为支持同步调用
        return YES;
        
    }
    - (BOOL)isExecuting
    {
        return _connection == nil; 
    }
    - (BOOL)isFinished
    {
        return _connection == nil;  
    }


    然后再UITableViewController里每个Cell创建的时候,如果没有图片的话,就通过ImageDownloader去下载,下载完了刷新这个Cell就可以了。

    #import <UIKit/UIKit.h>
    #import "ImageDownloader.h"
    @interface RootViewController : UITableViewController <imageDownloaderDelegate>
    {
        NSOperationQueue *queue;
        NSMutableArray *siteArray;
        NSMutableArray *imageArray;
        NSMutableDictionary *dic;
    }
    @property(nonatomic, retain)NSOperationQueue *queue;
    @property(nonatomic, retain)NSMutableArray *siteArray;
    @property(nonatomic, retain)NSMutableArray *imageArray;

    @end

     实现文件

    //
    //  RootViewController.m
    //  NSOperationTest
    //
    //

    #import "RootViewController.h"
    #import "ImageDownloader.h"
    #import "ImageTableViewCell.h"

    @implementation RootViewController
    @synthesize queue;
    @synthesize siteArray;
    @synthesize imageArray;

    - (void)dealloc
    {
        [self.queue release];
        [self.siteArray release];
        [self.imageArray release];
        [super dealloc];
    }

    - (void)viewDidLoad
    {
        [super viewDidLoad];
        self.queue = [[[NSOperationQueue alloc] init] autorelease];
        self.siteArray = [[[NSMutableArray alloc] init] autorelease];
        [self.siteArray addObject:@"http://s1.lashouimg.com/zt/201110/27/131972321636938600.jpg"];
        [self.siteArray addObject:@"http://s1.lashouimg.com/zt/201110/25/131953930325377400.jpg"];
        [self.siteArray addObject:@"http://s1.lashouimg.com/zt/201110/25/131953847613105000.jpg"];
        [self.siteArray addObject:@"http://s1.lashouimg.com/zt/201110/27/131972570125915500.jpg"];
        [self.siteArray addObject:@"http://s1.lashouimg.com/zt/201110/25/131954190510086200.jpg"];
        [self.siteArray addObject:@"http://s1.lashouimg.com/zt/201110/27/131972321636938600.jpg"];
        [self.siteArray addObject:@"http://s1.lashouimg.com/zt/201110/25/131953930325377400.jpg"];
        [self.siteArray addObject:@"http://s1.lashouimg.com/zt/201110/25/131953847613105000.jpg"];
        [self.siteArray addObject:@"http://s1.lashouimg.com/zt/201110/27/131972570125915500.jpg"];
        [self.siteArray addObject:@"http://s1.lashouimg.com/zt/201110/25/131954190510086200.jpg"];
        [self.siteArray addObject:@"http://s1.lashouimg.com/zt/201110/27/131972321636938600.jpg"];
        [self.siteArray addObject:@"http://s1.lashouimg.com/zt/201110/25/131953930325377400.jpg"];
        [self.siteArray addObject:@"http://s1.lashouimg.com/zt/201110/25/131953847613105000.jpg"];
        [self.siteArray addObject:@"http://s1.lashouimg.com/zt/201110/27/131972570125915500.jpg"];
        [self.siteArray addObject:@"http://s1.lashouimg.com/zt/201110/25/131954190510086200.jpg"];
        [self.siteArray addObject:@"http://s1.lashouimg.com/zt/201110/27/131972321636938600.jpg"];
        [self.siteArray addObject:@"http://s1.lashouimg.com/zt/201110/25/131953930325377400.jpg"];
        [self.siteArray addObject:@"http://s1.lashouimg.com/zt/201110/25/131953847613105000.jpg"];
        [self.siteArray addObject:@"http://s1.lashouimg.com/zt/201110/27/131972570125915500.jpg"];
        [self.siteArray addObject:@"http://s1.lashouimg.com/zt/201110/25/131954190510086200.jpg"];
        [self.siteArray addObject:@"http://s1.lashouimg.com/zt/201110/27/131972321636938600.jpg"];
        [self.siteArray addObject:@"http://s1.lashouimg.com/zt/201110/25/131953930325377400.jpg"];
        [self.siteArray addObject:@"http://s1.lashouimg.com/zt/201110/25/131953847613105000.jpg"];
        [self.siteArray addObject:@"http://s1.lashouimg.com/zt/201110/27/131972570125915500.jpg"];
        [self.siteArray addObject:@"http://s1.lashouimg.com/zt/201110/25/131954190510086200.jpg"];
        [self.siteArray addObject:@"http://s1.lashouimg.com/zt/201110/27/131972321636938600.jpg"];
        [self.siteArray addObject:@"http://s1.lashouimg.com/zt/201110/25/131953930325377400.jpg"];
        [self.siteArray addObject:@"http://s1.lashouimg.com/zt/201110/25/131953847613105000.jpg"];
        [self.siteArray addObject:@"http://s1.lashouimg.com/zt/201110/27/131972570125915500.jpg"];
        [self.siteArray addObject:@"http://s1.lashouimg.com/zt/201110/25/131954190510086200.jpg"];
        
        self.imageArray = [[[NSMutableArray alloc] init] autorelease];
        for ( int i = 0; i  < [self.siteArray count]; i++) 
        {
            [self.imageArray addObject: [NSNull null]];
        }
        dic = [NSDictionary dictionary];
        
    }

    // Customize the number of sections in the table view.
    - (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView
    {
        return 1;
    }

    - (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
    {
        return [siteArray count];
    }

    // Customize the appearance of table view cells.
    - (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        static NSString *CellIdentifier = @"Cell";
        
        ImageTableViewCell *cell = (ImageTableViewCell *)[tableView dequeueReusableCellWithIdentifier:CellIdentifier];
        if (cell == nil) 
        {
            NSArray *bundle = [[NSBundle mainBundle] loadNibNamed:@"ImageTableViewCell" owner:self options:nil];
            cell = (ImageTableViewCell *)[bundle objectAtIndex:0];
        }

        NSString *text = [NSString stringWithFormat:@"%d", indexPath.row];

        
        NSNull *null = (NSNull *)[self.imageArray objectAtIndex:indexPath.row];
        
        if (![null isKindOfClass:[NSNull class]])
        {
            [cell setCell:[imageArray objectAtIndex:indexPath.row] text:text];
      
        }
        else
        {
            [cell setCell:nil text:text];
            NSString *url = [self.siteArray objectAtIndex:indexPath.row];
            ImageDownloader *downloader = [[[ImageDownloader alloc] initWithURLString:url] autorelease];
            downloader.delegate = self;
            downloader.delPara = indexPath;
            [self.queue addOperation:downloader];
        }

        // Configure the cell.
        return cell;
    }

    - (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
    {
        return 112;
    }




    - (void)imageDidFinished:(UIImage *)image para:(NSObject *)obj
    {
        
        NSIndexPath *indexPath = (NSIndexPath *)obj;
        [self.imageArray replaceObjectAtIndex:indexPath.row withObject:image];
        ImageTableViewCell *cell = (ImageTableViewCell *)[self.tableView cellForRowAtIndexPath:indexPath];
        NSString *text = [NSString stringWithFormat:@"%d", indexPath.row];
        [cell setCell:image text:text];
        [cell setNeedsDisplay];

        
    }

    @end 

    本文是通过委托实现的刷新Cell,你也可以通过一个Observer,观察图片是否下载完成,完成后就刷新图片所再Cell。通过Observer如何实现请参考这个网址http://blog.csdn.net/kmyhy/article/details/6050345 

    本文地址:http://www.cnblogs.com/likwo/archive/2011/10/30/2229582.html

    demo项目下载 

  • 相关阅读:
    [转]Spring Cloud在国内中小型公司能用起来吗?
    [转]关于maven pom.xml中dependency type 为pom的应用
    如何直接在github网站上更新你fork的repo?
    Eclipse在Tomcat环境下运行项目出现NoClassDefFoundError/ClassNotFoundException解决办法
    Jquery mobile 中在列表项上使用单选按钮
    QBus 关注并推送实时公交信息
    常用序列号
    SVN 使用锁实现独占式签出
    SQL速记
    利用交通在手数据为换乘添加关注
  • 原文地址:https://www.cnblogs.com/likwo/p/2229582.html
Copyright © 2011-2022 走看看