iOS多线程简单使用

来源:互联网 发布:sip摄像机软件 编辑:程序博客网 时间:2024/06/09 07:30

      为什么要用多线程? 

       举个例子:在同一个程序里面,存在操作A,操作B假设操作A耗时5s,操作B耗时0.1s如果我先触发操作A接着马上触发操作B那么操作B的响应必定要在A结束以后才能执行;这样会影响用户体验。为什么会这样那? 因为操作AB都在同一个线程里面,线程的执行是具有顺序性的,A操作结束,才能进行下一个B操作。 但是A操作耗时较长,用户就需要等待5s后才能看到B操作的响应为了防止这样的事情发生,我们的方法是另外开辟一个线程。

     iOS多线程方法有以下三种:

     NSThread

     NSOperation

     GCD


      接下来我用以下例子讲述三种多线程的使用方法:

      如下界面两个label,  两个button, 点击A按钮执行操作 : 休眠5s  -> 将label1的内容变为"Good"   ;     点击B按钮: 将label2的内容直接变为“bad”

如果不使用多线程, 当点击完A之后, 马上点击B, 这个时候你会看到的过程是   A的响应完成之后,才去执行操作B, 使用多线程后, 我们会看到A,B操作互不干扰的执行。




GCD:

  • GCD是一种较为底层的多线程实现方式,其原理是将操作封装为block,并加入指定队列中开辟新线程执行。

  • NSOperation以及NSOperationQueue都是对GCD机制的高层封装。

    • 使用GCD可以实现更加灵活的多线程处理。


    dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0), ^{


        sleep(5); // 休眠5s


        //UI刷新的操作要在主线程中执行

        dispatch_async(dispatch_get_main_queue(), ^{


            self.label1.text =@"Good";

        });

        

    });


NSOperation:

  • NSOperation将一个操作封装成对象,并开辟一个新线程执行。

  • 可以将NSOperation对象加入NSOperationQueue队列中进行统一管理,放入队列中的NSOperation将并发执行。

  • 使用NSOperation需要子类化,并重写main方法,加入自定义操作。

  • NSOperation提供了子类来更加方便的初始化一个NSOperation对象:NSBlockOperation、NSInvocationOperation。



NSBlockOperation:

    NSOperationQueue * queue = [[NSOperationQueueallocinit];


    NSBlockOperation *blockOperation = [NSBlockOperationblockOperationWithBlock:^{

    //开辟线程做什么

        sleep(5);

    }];

  

    //线程结束后做什么

    [blockOperation setCompletionBlock:^{


        //要做的事情是刷新UI,所以放在主线程中

                dispatch_async(dispatch_get_main_queue(), ^{

                    self.label1.text =@"Good";

                });


    }];


    [queue addOperation:blockOperation];





NSInvocationOperation:

    NSOperationQueue *queue = [[NSOperationQueuealloc]init];

    NSInvocationOperation *operation = [[NSInvocationOperationalloc]initWithTarget:selfselector:@selector(sendWords)object:nil];

    [queue addOperation:operation];


-(void)sendWords

{

    sleep(3);    

    dispatch_async(dispatch_get_main_queue(), ^{

      self.label1.text =@"Good";

    });

}




NSThread:

  • NSThread可以简单开辟一个线程处理需要放到后台的操作。

  • NSThread 比其他两个轻量级。


    //类方法直接调用sendWords

    [NSThreaddetachNewThreadSelector:@selector(sendWords)toTarget:selfwithObject:nil];

    

    //对象方法,有点是可以设置对象相关参数,但是需要手动start

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

    thread.name =@"test";

    [thread start];



注释:

  • 同步执行:只要是同步执行的任务,都会在当前线程执行,不会另开线程。如果是 同步(sync) 操作,它会阻塞当前线程并等待 Block 中的任务执行完毕,然后当前线程才会继续往下运行
  • <code class="hljs objectivec has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">dispatch_sync</span>(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">dispatch_queue_t</span> queue, <<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#^(void)block#>)</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"></ul>
  • 异步执行:只要是异步执行的任务,都会另开线程,在别的线程执行。如果是 异步(async)操作,当前线程会直接往下执行,它不会阻塞当前线程。
    <code class="hljs objectivec has-numbering" style="display: block; padding: 0px; color: inherit; box-sizing: border-box; font-family: 'Source Code Pro', monospace;font-size:undefined; white-space: pre; border-radius: 0px; word-wrap: normal; background: transparent;"><span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">dispatch_async</span>(<span class="hljs-built_in" style="color: rgb(102, 0, 102); box-sizing: border-box;">dispatch_queue_t</span> queue, <<span class="hljs-preprocessor" style="color: rgb(68, 68, 68); box-sizing: border-box;">#^(void)block#>)</span></code><ul class="pre-numbering" style="box-sizing: border-box; position: absolute; width: 50px; top: 0px; left: 0px; margin: 0px; padding: 6px 0px 40px; border-right-width: 1px; border-right-style: solid; border-right-color: rgb(221, 221, 221); list-style: none; text-align: right; background-color: rgb(238, 238, 238);"></ul>

队列

  • 队列用于存放任务。一共有三种队列, 串行队列、并行队列和主队列。

  • 主队列:dispatch_get_main_queue()

  • 并行队列:dispatch_get_global_queue(long identifier, unsigned long flags)

  • 串行队列:dispatch_queue_create(const char *label, dispatch_queue_attr_t attr)


















1 0
原创粉丝点击