多线程

一.什么是多线程 把不同的任务放到不通的线程当中去,解决界面卡死问题 二.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;
}    

转载于:https://my.oschina.net/u/2433349/blog/688093

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值