IOS多线程

来源:互联网 发布:查看网络连接命令 编辑:程序博客网 时间:2024/06/17 13:12

(最近想总结下学过的东西,也算是正式步入码农之路了,如有错误之处,还请指正。)


1、先了解一下进程和线程的概念

进程:一个运行中的程序,程序本身不是一个进程,它只是存放在磁盘中的代码块而已,一旦被读取到内存中运行,它就成了一个进程。比如:电脑运行的QQ,WORD等都是一个进程。

线程:一个进程可以包含多个线程,比如:在QQ中刷朋友圈时,QQ还会接收消息。在word中编辑时,它还会执行保存等各种操作。

耗时操作:1.大量运算 2.各种网络请求 3.加载大文件4.睡眠代码

 耗时的操作不能放在主线程,因为这样会导致渲染界面代码执行不及时,出现界面堵塞状态,导致用户体验下降。

在IOS中修改界面的操作不能放在子线程中,如果放在子线程,因为子线程是一般处理耗时的操作,修改页面的代码要等到所有耗时的操作执行完之后才能看到效果,界面更新不及时。

 

2、创建线程的方法

(1)NSThread

  (2)GCD  :通过block开启线程 更底层 更高效代码简洁

  (3)NSOperation :可以灵活控制线程之间的关系 可以设置并发的线程数量

 

3、具体实现代码

(1)NSTread

- (IBAction)clicked:(id)sender

{

//   [self run];

    //开启新的线程去执行run方法

     [NSThread detachNewThreadSelector:@selector(run) toTarget:self withObject:nil];

    UIView *v = [[UIViewalloc]initWithFrame:CGRectMake(100,100, 100, 100)];

    v.backgroundColor = [UIColorredColor];

    [self.viewaddSubview:v];

    NSLog(@"我的所有的代码都执行完了");

   

}

-(void)run

{

    for (int i=0; i<5; i++)

    {

        [NSThread sleepForTimeInterval:1];

        UIView *v = [[UIViewalloc]initWithFrame:CGRectMake(100, i*100,100, 60)];

        v.backgroundColor = [UIColorgreenColor];

        //从子线程回到主线程的方法

        [self performSelectorOnMainThread:@selector(updateUI:)withObject:v waitUntilDone:NO];

    }

   

}

-(void)updateUI:(UIView *)v

{

[self.viewaddSubview:v];

//如果是其它的控件就要添加刷新显示

//[label setNeedsLayout];//刷新子控件显示

//[label setNeedsDisplay];//刷新自身显示

 

}

 

(2)GCD

 

(2)GCD

 -(void)viewDidLoad

{

//    线程队列

    //  并行队列:队列中的线程同时执行

    //  串行队列:队列中的线程依次执行

    // 开启子线程获取系统提供的线程队列(并行队列)

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{

        NSLog(@"子线程1开始");

        [NSThread sleepForTimeInterval:2];

        NSLog(@"子线程1结束");

    });

    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{

        NSLog(@"子线程2开始");

        [NSThread sleepForTimeInterval:2];

        NSLog(@"子线程2结束");


    ///创建串行线程队列

    dispatch_queue_t myQueue =dispatch_queue_create("myQueue",NULL);

    dispatch_async(myQueue, ^{

        NSLog(@"一号线程开始");

        [NSThread sleepForTimeInterval:1];

        NSLog(@"一号线程结束");

    });

    dispatch_async(myQueue, ^{

        NSLog(@"二号线程开始");

        [NSThread sleepForTimeInterval:1];

       

        NSLog(@"二号线程结束");

        //从子线程回到主线程

        dispatch_async(dispatch_get_main_queue(), ^{

            NSLog(@"这里回到了主线程");

        });

    });

 }

输出结果:

2015-04-27 09:36:01.930 GCD[885:43297] 一号线程开始

2015-04-27 09:36:01.930 GCD[885:43296] 子线程1开始

2015-04-27 09:36:01.930 GCD[885:43295] 子线程2开始

2015-04-27 09:36:02.936 GCD[885:43297] 一号线程结束

2015-04-27 09:36:02.936 GCD[885:43297] 二号线程开始

2015-04-27 09:36:03.936 GCD[885:43296] 子线程1结束

2015-04-27 09:36:03.936 GCD[885:43295] 子线程2结束

2015-04-27 09:36:03.936 GCD[885:43297] 二号线程结束

2015-04-27 09:36:03.937 GCD[885:43214] 这里回到了主线程



====================================

(3)NSOperation

NSOperation* op1 =[[NSInvocationOperationalloc]initWithTarget:selfselector:@selector(run)object:nil];

    NSOperation* op2 =[NSBlockOperationblockOperationWithBlock:^{

        for (int i =0; i< 5; i ++)

        {

            [NSThread sleepForTimeInterval:2];

            NSLog(@"线程2");

        }

    } ];

    //   [op2 start]; 开启线程

    //添加op1的依赖

    [op1 addDependency:op2];

   

    NSOperationQueue* myQueue = [[NSOperationQueuealloc]init];

    //设置最大的线程并行数量如果为1的话就相当于串行

    [myQueue setMaxConcurrentOperationCount:1];

    //添加到队列开启线程

    [myQueue addOperation:op1];

    [myQueue addOperation:op2];

 

 输出结果:

2015-04-27 09:44:05.493 NSOperation[993:49305] 线程一  0

2015-04-27 09:44:07.499 NSOperation[993:49305] 线程一  1

2015-04-27 09:44:09.505 NSOperation[993:49305] 线程一  2

2015-04-27 09:44:11.509 NSOperation[993:49305] 线程一  3

2015-04-27 09:44:13.511 NSOperation[993:49305] 线程一  4



=========================================

//        线程同步方式:1.同步代码块

//       参数要一个对象必须同一个对象对象内部有一个锁的表示

//        @synchronized(self){

//        2.使用NSLock对象

//        [self.myLock lock];

//        3.NSCondition对象

 

    self.totalCount =100;

    self.myLock = [[NSLockalloc] init];

    self.myCondition = [[NSConditionalloc] init];

   

      NSThread* t1 = [[NSThreadalloc]initWithTarget:selfselector:@selector(salesChicket)object:nil];

    [t1 setName:@"窗口一"];

    [t1 start];

    NSThread* t2 = [[NSThreadalloc]initWithTarget:selfselector:@selector(salesChicket)object:nil];

    [t2 setName:@"窗口二"];

    [t2 start];

   


 

-(void)salesChicket

{

    NSString* name = [NSThreadcurrentThread].name;

    //开启同步

    //线程同步方式:1.同步代码块

    //       2.使用NSLock对象

    //       [self.myLock lock];

    //       3.NSCondition对象

    //参数要一个对象必须同一个对象对象内部有一个锁的表示

   // @synchronized(self)//使同步

   // {

    //[self.myLock lock];

    [self.myConditionlock];

        NSLog(@"%@开始卖%d号票",name,self.salesCount+1);

        [NSThread sleepForTimeInterval:.5];

        self.salesCount++;

        NSLog(@"%@卖票结束卖了%d号票还剩%d",name,self.salesCount,self.totalCount-self.salesCount);

    //}

    //[self.myLock unlock];

[self.myConditionunlock];

 

  


 


 

 

 

 

 

 

 

0 0