IOS 多线程编程之NSOperationQueue

创建任务队列
_opQueue=[[NSOperationQueue alloc]init];
设置同时执行任务的个数
[_opQueue setMaxConcurrentOperationCount:3];

添加一条任务
NSInvocationOperation*opt01=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(updateP1) object:nil];

将任务一添加到任务队列中
[_opQueue addOperation:opt01];
添加多条任务

NSMutableArray *arrayOp=[[NSMutableArray alloc]initWithCapacity:0];

for (int i=0; i<3; i++)
{
    //创建三个任务
    //3个对象来执行同一个函数
    //需要三个线程来分别执行这个函数
    NSInvocationOperation*op=[[NSInvocationOperation alloc]initWithTarget:self selector:@selector(updateArray) object:nil];

    [arrayOp addObject:op];
}
    //将任务数组添加到任务队列中,及时添加队列,不需要等待
[_opQueue addOperations:arrayOp waitUntilFinished:NO];

//添加一个block语法任务
[_opQueue addOperationWithBlock:^{

    int i=0;
    while (true)
    {
        i++;
        NSLog(@"i=%d",i);
        if (i>1000)
        {
            break;
        }
    }
}];

应用举例 1.
如何多并发的处理十条任务,比如用三个并发的任务处理 10个进度条?

- (void)viewDidLoad {
    [super viewDidLoad];
    _arrayProgress = [[NSMutableArray alloc] init];

    for (int i = 0 ; i < 10; i++){
    UIProgressView *pView = [[UIProgressView alloc] initWithProgressViewStyle:UIProgressViewStyleDefault];
        pView.frame = CGRectMake(10, 40+i*40, 300, 40);
        pView.progress = 0 ;
        [_arrayProgress addObject:pView];
        [self.view addSubview:pView];
        pView.tag = 101+i;
    }

    //创建任务队列(线程池)
    _opQueue = [[NSOperationQueue alloc] init];
        //设置同时可以执行的任务的个数
    [_opQueue setMaxConcurrentOperationCount:3];
    int max = (int)_opQueue.maxConcurrentOperationCount;
    NSLog(@"max = %d",max);
    _lock = [[NSLock alloc]init];

}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {

    NSInvocationOperation *op01 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(updateProgress01) object:nil];
    [_opQueue addOperation:op01];

    NSInvocationOperation *op02 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(updateProgress02) object:nil];
    [_opQueue addOperation:op02];

    NSInvocationOperation *op03 = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(updateProgress03) object:nil];
    [_opQueue addOperation:op03];

    _cnt = 0;
    _cnt01 = 1;
    _cnt02 = 1;
    _cnt03 = 1;
}

- (void)updateProgress01 {

    while (_cnt < 11) {
        [_lock lock];
        _cnt++;
        _cnt01 = _cnt;
        [_lock unlock];

    while (_curProgress01 <= 1){
        NSLog(@"%f",_curProgress01);
        _curProgress01 += 0.0005;
        NSThread *mainT = [NSThread mainThread];
        [self performSelector:@selector(changeThread) onThread:mainT withObject:nil waitUntilDone:YES];
       }
        _curProgress01 = 0;
    }

}
- (void)changeThread {
    UIProgressView *pView = (UIProgressView *)[self.view viewWithTag:100+_cnt01];
    pView.progress = _curProgress01;
}

- (void)updateProgress02 {

    while (_cnt < 11) {
        [_lock lock];
        _cnt ++;
        _cnt02 = _cnt;
        [_lock unlock];
    while (_curProgress02 <= 1) {
        _curProgress02 += 0.00005;

        NSThread *mainT = [NSThread mainThread];

        [self performSelector:@selector(changeThread02) onThread:mainT withObject:nil waitUntilDone:YES];

       }
        _curProgress02 = 0;
    }
}
- (void)changeThread02 {
    UIProgressView *pView = (UIProgressView *)[self.view viewWithTag:100+_cnt02];
    pView.progress = _curProgress02;
}


- (void)updateProgress03 {
    while (_cnt < 11) {
        [_lock lock];
        _cnt ++;
        _cnt03 = _cnt;
        [_lock unlock];

    while (_curProgress03 <= 1) {
        _curProgress03 += 0.00005;
        NSThread *mainT = [NSThread mainThread];
        [self performSelector:@selector(changeThread03) onThread:mainT withObject:nil waitUntilDone:YES];

         }
        _curProgress03 = 0;
    }
}
- (void)changeThread03 {
    UIProgressView *pView = (UIProgressView *)[self.view viewWithTag:100+_cnt03];
    pView.progress = _curProgress03;
}

应用举例2
并发处理十张图片的下载,没点击一次,增加一条任务,处理下载图片,最大并发数为10 ,如果一直在点击的话,最多同时处理10条任务,但是任务队列就不止10条,点击多少次,则执行了多少次.

@implementation FKViewController
NSOperationQueue* queue;
- (void)viewDidLoad
{
    [super viewDidLoad];
    queue = [[NSOperationQueue alloc]init];
    // 设置该队列最多支持10条并发线程
    queue.maxConcurrentOperationCount = 10;
}
- (IBAction)clicked:(id)sender
{
    NSString* url = @"http://www.crazyit.org/logo.jpg";
    // 以self的downloadImageFromURL:方法作为执行体,创建NSOperation
    NSInvocationOperation* operation = [[NSInvocationOperation alloc]
        initWithTarget:self selector:@selector(downloadImageFromURL:)
        object:url];
    // 将NSOperation添加给NSOperationQueue
    [queue addOperation:operation];
}

// 定义一个方法作为线程执行体。
-(void)downloadImageFromURL:(NSString *) url
{
    // 从网络获取数据
    NSData *data = [[NSData alloc]
        initWithContentsOfURL:[NSURL URLWithString:url]];
    // 将网络数据初始化为UIImage对象
    UIImage *image = [[UIImage alloc]initWithData:data];
    if(image != nil)
    {
        // 在主线程中执行updateUI:方法
        [self performSelectorOnMainThread:@selector(updateUI:)
            withObject:image waitUntilDone:YES];
    }
    else
    {
        NSLog(@"---下载图片出现错误---");
    }
}
-(void)updateUI:(UIImage*) image
{
    self.iv.image = image;
}
@end

封装一下

@implementation FKViewController
NSOperationQueue* queue;
- (void)viewDidLoad
{
    [super viewDidLoad];
    queue = [[NSOperationQueue alloc]init];
    // 设置该队列最多支持10条并发线程
    queue.maxConcurrentOperationCount = 10;
}
- (IBAction)clicked:(id)sender
{
    // 定义要加载的图片的URL
    NSURL* url = [NSURL URLWithString:@"http://www.crazyit.org/logo.jpg"];
    // 创建FKDownImageOperation对象
    FKDownImageOperation* operation = [[FKDownImageOperation alloc]
        initWithURL:url imageView:self.iv];
    // 将NSOperation的子类的实例提交给NSOperationQueue
    [queue addOperation:operation];
}
@implementation FKDownImageOperation
- (id)initWithURL:(NSURL*)url imageView:(UIImageView*)iv
{
    self = [super init];
    if (self) {
        _imageView = iv;
        _url = url;
    }
    return self;
}
// 重写main方法,该方法将作为线程执行体
- (void)main
{   
    // 从网络获取数据
    NSData *data = [[NSData alloc]
        initWithContentsOfURL:self.url];
    // 将网络数据初始化为UIImage对象
    UIImage *image = [[UIImage alloc]initWithData:data];
    if(image != nil)
    {
        // 在主线程中执行updateUI:方法
        [self performSelectorOnMainThread:@selector(updateUI:)
            withObject:image waitUntilDone:YES]; // ①
    }
    else
    {
        NSLog(@"---下载图片出现错误---");
    }
}
-(void)updateUI:(UIImage*) image
{
    self.imageView.image = image;
}

利用[NSBlockOperation
blockOperationWithBlock:^{}
]让代码更加紧凑



@implementation FKViewController NSOperationQueue* queue; - (void)viewDidLoad { [super viewDidLoad]; queue = [[NSOperationQueue alloc]init]; // 设置该队列最多支持10条并发线程 queue.maxConcurrentOperationCount = 10; } - (IBAction)clicked:(id)sender { NSString* url = @"http://www.crazyit.org/logo.jpg"; // 以传入的代码块作为执行体,创建NSOperation NSBlockOperation* operation = [NSBlockOperation blockOperationWithBlock:^{ // 从网络获取数据 NSData *data = [[NSData alloc] initWithContentsOfURL:[NSURL URLWithString:url]]; // 将网络数据初始化为UIImage对象 UIImage *image = [[UIImage alloc]initWithData:data]; if(image != nil) { // 在主线程中执行updateUI:方法 [self performSelectorOnMainThread:@selector(updateUI:) withObject:image waitUntilDone:YES]; } else { NSLog(@"---下载图片出现错误---"); } }]; // 将NSOperation添加给NSOperationQueue [queue addOperation:operation]; } -(void)updateUI:(UIImage*) image { self.iv.image = image; }

你可能感兴趣的:(IOS 多线程编程之NSOperationQueue)