1.NSOperationQueue:代表一个FIFO的队列,它负责管理系统提交的多个NSOperation,NSOperationQueue底层维护一个线程池,会按顺序启动线程来执行提交给该队列的NSOperation任务。
NSOperation:代表一个多线程任务。NSOperation还有NSInvocationOperation.NSBlockOperation两个子类。
NSOperation有两种使用方式:
方式1:开发者实现NSOperation的子类
方式2:直接使用NSInvocationOperation或NSBlockOperation子类。
2.使用NSBlockOperation子类
queue = [[NSOperationQueue alloc]init];
//设置该队列最大支持10个并发线程
queue.maxConcurrentOperationCount = 10;
NSString *url = @"http://www.crazyit.org/logo.jpg";
//以传入的代码块作为执行体,创建NSOperation
NSBlockOperation *operation = [NSBlockOperation blockOperationWithBlock:^{
//从网络获取数据
NSData *data = [[NSData alloc]initWithContentsOfURL:[NSURL URLWithString:url]];
UIImage *image = [[UIImage alloc]initWithData:data];
if (image!=nil) {
//在主线程中执行updateUI方法
[self performSelectorOnMainThread:@selector(updateUI:) withObject:imagewaitUntilDone:YES];
}
else
{
NSLog(@"下载图片出现错误");
}
}];
[queue addOperation:operation];
3. 定义NSOperation子类
NSOperation一般不会直接拿来使用,而是选择创建它的子类,创建NSOperation的子类需要重写main方法。(写的方法似乎不会被调用,可以在init方法直接调用)
定义子类STDownOperation
//.m
- (id)initWithURL:(NSURL *)url imageView:(UIImageView *)iv
{
self = [super init];
if (self) {
_imageView = iv;
_url = url;
[self main];
}
return self;
}
//重写main方法,该方法将作为线程执行体:为什么不执行?
- (void)main
{
//从网络获取数据
NSData *data = [[NSData alloc]initWithContentsOfURL:self.url];
UIImage *image = [[UIImage alloc]initWithData:data];
if (image!=nil) {
//在主线程中更新UI
[self performSelectorOnMainThread:@selector(updateUI:) withObject:imagewaitUntilDone:YES];
}
else
{
NSLog(@"下载图片出现错误");
}
}
- (void)updateUI:(UIImage *)image
{
self.imageView.image = image;
}
//.h
@property (nonatomic, strong)NSURL *url;
@property (nonatomic, strong)UIImageView *imageView;
- (id)initWithURL:(NSURL *)url imageView:(UIImageView *)iv;
然后调用该类
- (void)clicked:(UIButton *)sender
{
NSString *url = @"http://www.crazyit.org/logo.jpg";
STDownOperation *operation = [[STDownOperation alloc]initWithURL:[NSURLURLWithString:url] imageView:imageView];
[queue addOperation:operation];
}