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];
    

你可能感兴趣的:(image,null,url,iPhone,interface,Dictionary)