iOS多线程技术的深度探究三: NSOperation多线程技术

/*
 2. NSOperation
    1> NSInvocationOperation
    2> NSBlockOperation
 
    定义完operation之后,将操作添加到NSOperationQueue中即可启动线程,执行任务
 
    使用:
    1> setMaxConcurrentOperationCount 可以控制同时并发的线程数量
    2> addDependency 可以指定线程之间的依赖关系,从而达到控制线程的执行顺序的目的
 
    提示:
    要更新UI,需要使用[NSOperationQueue mainQueue] addOperationWithBlock:
    方法在主操作队列中更新界面
 */
#define SCREENWIDTH       [UIScreen mainScreen].bounds.size.width
#define SCREENHEIGHT      [UIScreen mainScreen].bounds.size.height
#define W                 SCREENWIDTH/4
#define H                 (SCREENHEIGHT-50)/7
#define RANDOMDATA        (float)arc4random_uniform(256)/255


#import "ViewController.h"


@interface ViewController ()
{
    NSSet *viewSet;
    //定义操作队列
    NSOperationQueue *operationQueue;
}
@end


@implementation ViewController




- (void)viewDidLoad {
    [super viewDidLoad];
    [self setSubview];
    //实例化操作队列
    operationQueue = [[NSOperationQueue alloc] init];
    // Do any additional setup after loading the view, typically from a nib.
}


- (void)setSubview
{
    //实例化视图集合
    NSMutableSet *myViewSet = [NSMutableSet setWithCapacity:28];
    for (int row = 0; row < 7; row++) {
        for (int col = 0; col < 4; col++) {
            //计算view的位置
            int x = col * W;
            int y = row * H;
            
            UIView *view = [[UIView alloc] initWithFrame:CGRectMake(x, y, W, H)];
            view.backgroundColor = [UIColor colorWithRed:RANDOMDATA green:RANDOMDATA blue:RANDOMDATA alpha:1];
            [self.view addSubview:view];
            [myViewSet addObject:view];
        }
    }
    viewSet = myViewSet;
    
    //添加按钮
    UIButton *button = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [button setFrame:CGRectMake(0, SCREENHEIGHT-50, SCREENWIDTH/2, 50)];
    [button setBackgroundColor:[UIColor blackColor]];
    [button setTitle:@"刷新图片" forState:UIControlStateNormal];
    [button addTarget:self action:@selector(didButtonClicked:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:button];
    
    UIButton *button1 = [UIButton buttonWithType:UIButtonTypeRoundedRect];
    [button1 setFrame:CGRectMake(SCREENWIDTH/2, SCREENHEIGHT-50, SCREENWIDTH/2, 50)];
    [button1 setBackgroundColor:[UIColor blackColor]];
    [button1 setTitle:@"线程顺序控制" forState:UIControlStateNormal];
    [button1 addTarget:self action:@selector(didButton1Clicked:) forControlEvents:UIControlEventTouchUpInside];
    [self.view addSubview:button1];
}


#pragma mark - 多线程:NSThread加载图片
- (IBAction)didButtonClicked:(id)sender
{
    NSLog(@"点击我!");
    [self operationBlockLoadColorView];
}


- (IBAction)didButton1Clicked:(id)sender
{
    NSLog(@"点击我!");
    [self operationDemo];
}


- (void)loadColorView:(UIView *)view
{
    //多线程一定要加入到自动释放池中
    @autoreleasepool {
        NSLog(@"%@",[NSThread currentThread]);
        //当前线程睡眠
        //    [NSThread sleepForTimeInterval:1];
        //在主线程队列中更新UI
        [[NSOperationQueue mainQueue] addOperationWithBlock:^{
            [view setBackgroundColor:[UIColor colorWithRed:RANDOMDATA green:RANDOMDATA blue:RANDOMDATA alpha:1]];
        }];
    }
}


#pragma mark - NSOperation控制线程的执行顺序
- (void)operationDemo
{
    NSBlockOperation *blockOperation1 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"下载:%@",[NSThread currentThread]);
    }];
    NSBlockOperation *blockOperation2 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"美化:%@",[NSThread currentThread]);
    }];
    NSBlockOperation *blockOperation3 = [NSBlockOperation blockOperationWithBlock:^{
        NSLog(@"更新:%@",[NSThread currentThread]);
    }];
    
    //Dependency(依赖)
    //提示:依赖关系可以多重依赖,并且可以跨队列依赖:即创建两个队列,相互之间建立依赖关系
    //注意:不能建立循环依赖
    [blockOperation2 addDependency:blockOperation1];
    [blockOperation3 addDependency:blockOperation2];
    
    [operationQueue addOperation:blockOperation1];
    [operationQueue addOperation:blockOperation2];
    [operationQueue addOperation:blockOperation3];
}


#pragma mark - 多线程:NSOpreation加载图片
- (void)operationBlockLoadColorView
{
        for (UIView *colorView in viewSet) {
            NSBlockOperation *blockOperation = [NSBlockOperation blockOperationWithBlock:^{
                [self loadColorView:colorView];
            }];
            [operationQueue addOperation:blockOperation];
        }
}


- (void)operationLoadColorView
{
        for (UIView *colorView in viewSet) {
        //队列可以控制同时并发的线程数
        [operationQueue setMaxConcurrentOperationCount:2];
        NSInvocationOperation *invocationOperation = [[NSInvocationOperation alloc] initWithTarget:self selector:@selector(loadColorView:) object:colorView];
        //如果直接调用operation的start方法是在主线程中执行的,不会开启新的线程
//            [invocationOperation start];
        //将operation添加到队列,一添加到队列,任务就会开启新的线程执行任务
        [operationQueue addOperation:invocationOperation];
        }
}
- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}


@end

你可能感兴趣的:(iOS多线程专辑)