多线程编程(一)NSThread

     在iOS中每个进程启动后都会建立一个主线程(UI线程),这个线程是其他线程的父线程。由于在iOS中除了主线程,其他子线程是独立于Cocoa Touch的,所以只有主线程可以更新UI界面(新版iOS中,使用其他线程更新UI可能也能成功,但是不推荐)。iOS中多线程使用并不复杂,关键是如何控制好各个线程的执行顺序、处理好资源竞争问题。 

   多线程开发中,需要明白一点,cpu在同一时间内,只能处理一件事情,多线程开发,只是cpu在各个线程之间来回穿梭调度,并不是cpu能够同时执行多个任务,这一需要明确,本篇博客主要讲一下NSThread

 一   NSThread的创建有三种方式

    //第一种  先创建 再启动  注意 object参数 如果down方法需要参数 就在object这里把参数传递给down方法

    NSThread * thread = [[NSThread alloc]initWithTarget:self selector:@selector(down) object:nil];

    [thread start];

     //第二种 创建 不用启动

    [self performSelectorInBackground:@selector(down) withObject:nil];

    //第三种 创建 不用启动

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

把比较耗时的操作放在down方法中,但是不要把UI的更新放在down方法中。

 取消线程  [thread cancel];线程执行完操作后 会自动销毁,也就是说 一个线程只能处理一个任务

 

二  线程之间的通信 ,比如在子线程中下载一张图片,下载完要回到主线程刷新UI;

    [self performSelectorOnMainThread:@selector(update:) withObject:img waitUntilDone:YES];

这句代码中的withObject:后面的参数img就是下载的图片,然后在update:方法中 给imgView赋值,

这句代码还有一种表达方式

    [self performSelector:@selector(update:) onThread:[NSThread mainThread] withObject:img waitUntilDone:YES];

 其实这里还有一种比较简单的方法 不用写update方法了 既然给imgView赋值  直接这样写

    [self.myImgView performSelector:@selector(setImage:) onThread:[NSThread  mainThread] withObject:img waitUntilDone:YES];

 三 线程间的安全问题

如果我们的多个线程对同一个资源同时访问,可能就会产生问题,比如我们的卖票问题,比如开了三个线程卖票,共有10张票,线程一访问时是10张,当线程一访问完后,线程二又马上来访问,线程二访问时还是10张,线程二访问完后,线程一卖了一张票,此时线程一返回给服务器的值是10-1 = 9张票,此时线程二也卖了一张,线程二返回的肯定也是10-1=9张,这样肯定是有问题的,为了避免这种情况,此时我们要为共同访问的资源加锁,还是直接上代码。

    self.thread1 = [[NSThread alloc]initWithTarget:self selector:@selector(saleTicket) object:nil];

    self.thread1.name = @"窗口1";

    self.thread2 = [[NSThread alloc]initWithTarget:self selector:@selector(saleTicket) object:nil];

    self.thread2.name = @"窗口2";

    self.thread3 = [[NSThread alloc]initWithTarget:self selector:@selector(saleTicket) object:nil];

    self.thread3.name = @"窗口3";

    [self.thread1 start];

    [self.thread2 start];

    [self.thread3 start];

 

        @synchronized(self){

          int count = self.leftTicketCount;

           if (count > 0) {

              self.leftTicketCount = count - 1;

              NSLog(@"%@卖了1张票,还剩%d张票",[NSThread currentThread].name,self.leftTicketCount);

            }else{

             return;

            }

        }

 其实@synchronized()就是加锁,后面小括号里面就是锁对象, 锁对象的可以是任意的对象,可以直接用self,注意 锁要用一个 不能每次创建一个 那样和没加锁是一样的效果,

 NSThread的大体用法就这些,现在已经不是太常用NSThread 了 主要是用GCD 和NSOperation 另外还有一种Pthread  几乎不用,有兴趣的可以了解下,GCD和NSOperation会在后面的章节写下,哪里有不对的地方,欢迎大家评批指正。

 

posted on 2015-08-04 15:52  键盘上的舞者LQB  阅读(223)  评论(0编辑  收藏  举报

导航