Fork me on GitHub

iphone中使用NSoperation实现图片异步加载

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

1。定义ImageTableViewCell 

 

1
2
3
4
5
6
7
8
9
@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

方法添加如下 

 

 

1
2
3
4
5
6
7
8
9
10
- (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方法就好了。

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
#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

实现文件如下

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#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

实现文件

 

 

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
//
//  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.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

posted on 2012-02-19 03:00  pengyingh  阅读(309)  评论(0编辑  收藏  举报

导航