多线程

一.什么是多线程
        把不同的任务放到不通的线程当中去,解决界面卡死问题
二.NSThread
    2.1 三种创建线程方式
      //第一种创建线程的方式
     [self performSelectorInBackground:@selector(thread1) withObject:nil];

       //创建线程的第二种方式
      [NSThread detachNewThreadSelector:@selector(thread2:) toTarget:self withObject:@(100)];

      //创建线程的第三种方式
      NSThread *thread = [[NSThread alloc]initWithTarget:self selector:@selector(thread3) object:nil];
    [thread setName:@"thread3"];
    [thread start];

    2.2 监听线程结束
    [[NSNotificationCenter defaultCenter]addObserver:self selector:@selector(myThreadFinish:) name:NSThreadWillExitNotification object:nil];

    - (void)myThreadFinish:(NSNotification *)notification
    {
            NSThread *thread = [notification object];
            if ([thread.name isEqualToString:@"thread3"])
            {
                    NSLog(@"thread3 finish!");
            }
            NSLog(@"thread ===%@",thread);
    }

     2.3 线程间通讯
       - (void)thread4
    {
            for (int i = 0; i<10; i++)
            {
                    NSLog(@"thread4  i===%d",i);
                    [NSThread sleepForTimeInterval:1.0];
        
                if (i == 8)
                {
                        //给_thread5发cancel消息.仅仅只是发消息,处不处理,由_thread5自己决定
                        [_thread5 cancel];
                }
            }
    }

    - (void)thread5
    {
            int i = 0;
            while (1)
            {
                    NSLog(@"thread5===%d",i);
                  [NSThread sleepForTimeInterval:1.0];
                   i++;
                    //如果thread5 接收到了cancel消息,就退出
                    if ([[NSThread currentThread]isCancelled])
                   {
                        NSLog(@"thread5  exit");
                    //执行线程退出
                    [NSThread exit];
                    }
           }
    }

    2.4 线程锁
    _sumLock  = [[NSLock alloc]init];
        _sum = 0;

    [_sumLock lock];
            _sum ++;
            [NSThread sleepForTimeInterval:1.0];
            [_sumLock unlock];

    2.5 子线程刷新UI
    _progress = [[UIProgressView alloc]initWithFrame:CGRectMake(100, 100, 200, 30)];
                [self.view addSubview:_progress];
    
                [self performSelectorInBackground:@selector(myThread) withObject:nil];
    
    - (void)myThread
            {
                    for (int i=1; i<11; i++)
                    {
                        [self performSelectorOnMainThread:@selector(myMain:) withObject:@(i) waitUntilDone:YES];
                        [NSThread sleepForTimeInterval:1];
                }
            }
    
        - (void)myMain:(NSNumber *)number
        {
                NSLog(@"number==%@",number);
                [_progress setProgress:number.floatValue*0.1 animated:YES];
        }
三.NSOperationQueue
        3.1 NSInvocationOperation
            NSInvocationOperation *operation1= [[NSInvocationOperation alloc]initWithTarget:self selector:@selector(myOperation1) object:nil];

        3.2 NSBlockOperation
            NSBlockOperation *operation2 = [NSBlockOperation blockOperationWithBlock:^{
                            NSLog(@" i am operation2");
                         [NSThread sleepForTimeInterval:5];
                    }];

            3.3 自定义的operation
            NSArray *urlArrays = [NSArray arrayWithObjects:@"http://s8.mogucdn.com/pic/141109/49ssv_ieydmolegjsdqyzwmqytambqgiyde_173x80.jpg", @"http://s8.mogucdn.com/pic/141118/7jax4_ieydkntggvrwknzzmqytambqmmyde_173x80.jpg", @"http://s7.mogucdn.com/pic/141111/anxuan_ieygkyjzgnsdanrxmqytambqmmyde_173x80.jpg", nil];
    
    for (int i = 0; i<3; i++)
    {
        UIImageView *imgView = [[UIImageView alloc]initWithFrame:CGRectMake(10, 30+110*i, 100, 100)];
        imgView.tag = 100+i;
        imgView.backgroundColor = [UIColor blackColor];
        [self.view addSubview:imgView];
    }
    //创建任务池
    NSOperationQueue *queue = [[NSOperationQueue alloc]init];
    queue.maxConcurrentOperationCount = 1;
    
    for (int i =0; i<urlArrays.count; i++)
    {
        MyOperation *operation = [[MyOperation alloc]initWithURL:[urlArrays objectAtIndex:i] completionCallBack:^(MyOperation *operation, NSData *data) {
            //取到和operation对应的UIImageView
            UIImageView *imgView =(UIImageView *) [self.view viewWithTag:operation.tag];
            UIImage *image = [UIImage imageWithData:data];
            imgView.image = image;

        }];
        operation.tag = 100+i;
        [queue addOperation:operation];
    }

@class MyOperation;
//回调的blocks
typedef void (^completionCallBack)(MyOperation *operation,NSData *data);

@interface MyOperation : NSOperation<NSURLConnectionDataDelegate>
//tag的作用是为了和imgview对应
@property (nonatomic,assign)int tag;
- (id)initWithURL:(NSString *)URL completionCallBack:(completionCallBack)callback;

- (void)main
{
    NSURL *url = [NSURL URLWithString:_url];
    NSURLRequest *request = [NSURLRequest requestWithURL:url];
    [NSURLConnection connectionWithRequest:request delegate:self];
    
    NSLog(@"distantFutureTime===%@",[[NSDate distantFuture]description]);
    if (!_isfinishDownload) {
//        NSRunLoop  是一个循环事件,每一个viewcontroller都有一个runloop
//        NSRunLoop 有任务就坐任务,没任务就等待
//        [NSDate distantFuture]  永远不会到达的时间
        NSLog(@"currentRunLoop");
        [[NSRunLoop currentRunLoop]runMode:NSDefaultRunLoopMode beforeDate:[NSDate distantFuture]];
    }
}
            3.4只有将operation加入到线程池,方可运行
            NSOperationQueue *queue = [[NSOperationQueue alloc]init];
            queue.maxConcurrentOperationCount =2;
            //将operation添加进线程池,operation添加进线程池,立刻开始运行
                [queue addOperation:operation1];
                 [queue addOperation:operation2];
                [queue addOperation:operation3];
                
四.GCD
    4.1GCD种类
    /第一种,取得主线程:ios自带
    _mainQueue = dispatch_get_main_queue();
    
    //第二种,取得全局的一个线程:ios自带
    _globalQueue = dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0);
    
    //第三种GCD多线程,用户自己创建的线程
    //第一个参数:myQueue   是一个字符串,作标识
    //第二个参数:这个GCD队列是串行还是并行
    //DISPATCH_QUEUE_SERIAL  串行
    //DISPATCH_QUEUE_CONCURRENT  并行
    //串行  就是队列里面,挨个执行.先来的先执行
    //并行  一起上
    _userQueue = dispatch_queue_create("myQueue", DISPATCH_QUEUE_SERIAL);

    4.2 GCD调度方式
    //同步方式进行调用==串行
    dispatch_sync(<#dispatch_queue_t queue#>, <#^(void)block#>)
    //异步方式进行调用==并行
    dispatch_async(<#dispatch_queue_t queue#>, <#^(void)block#>)

    //    _mainQueue  不管你用何种方式去调度它,它都是串行
    //主线程不要使用同步的方式进行调度,会阻塞UI
    dispatch_async(_mainQueue, ^{
        NSLog(@"1");
    });
    dispatch_async(_mainQueue, ^{
        NSLog(@"2");
    });

    //_globalQueue 全局队列
    //如果使用dispatch_sync  同步方式去调度,就是串行
    //如果使用dispatch_async 异步方式进行调度,就是并行
    dispatch_sync(_globalQueue, ^{
        NSLog(@"A");
    });
    dispatch_sync(_globalQueue, ^{
        NSLog(@"B");
    });

    //用户自己创建的队列
    //用户自己创建的队列,只要是用同步方式进行调度(dispatch_sync),则一定是串行
    //只有异步调用(dispatch_async)+ DISPATCH_QUEUE_CONCURRENT(并行)才是并行调用
    dispatch_async(_userQueue, ^{
        NSLog(@"a");
    });
    dispatch_async(_userQueue, ^{
        NSLog(@"b");
    });

    4.3 GCD刷UI
    _progress = [[UIProgressView alloc]initWithFrame:CGRectMake(50, 100, 200, 30)];
    _progress.progress = 0;
    [self.view addSubview:_progress];

    dispatch_async(_globalQueue, ^{
        for ( int i = 1; i<11; i++)
        {
            float value = i*0.1;
            [NSThread sleepForTimeInterval:1.0];
            dispatch_async(_mainQueue, ^{
                    [_progress setProgress:value animated:YES];
            });
        }
    });

    // GCD单例写法
    + (id)shareInstance
    {
            static dispatch_once_t onceToken;
            static ViewController * ctl = nil;
            dispatch_once(&onceToken, ^{
            // 保证下面的代码只会执行一次
            ctl = [[ViewController alloc] init];
                });
            return ctl;
    }    


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值