zoukankan      html  css  js  c++  java
  • swift开发多线程篇

    一 说明
    
    本文涉及代码可以从https://github.com/HanGangAndHanMeimei/Code地址获得。
    
    二 NSThread的基本使用和创建
    
      1)基本用法(主线程|当前线程)
    
     1        //1.获得执行该方法的当前线程
     2         let currentThread = NSThread.currentThread()
     3         print("当前线程为(currentThread)")
     4 
     5         //2.获得应用程序的主线程
     6         let mainThread = NSThread.mainThread()
     7         print("应用程序的主线程(mainThread)")
     8 
     9         //3.判断当前线程是否是主线程
    10         let isMain =  NSThread.isMainThread() 
    
    2)创建线程
    
      说明:此处列出创建线程的四种方法:分别是
    
      直接创建|分离出一条子线程|创建一条后台线程|自定义线程类继承自NSThread重写内部的main方法封装任务,然后init创建。
    
     1 //NSThread创建线程的四种方式
     2     func createNewThreadWithNSThreadMethodOne()
     3     {
     4         //1.创建线程
     5         let thread = NSThread.init(target: self, selector:Selector("run"), object: nil)
     6 
     7         //设置线程的名称
     8         thread.name = "线程A"
     9 
    10         //2.启动线程
    11         thread.start()
    12     }
    13 
    14     func createNewThreadWithNSThreadMethodTwo()
    15     {
    16         //分离出一条子线程,自动启动线程,但无法获得线程对象
    17         NSThread.detachNewThreadSelector(Selector("run"), toTarget: self, withObject: nil)
    18     }
    19 
    20     func createNewThreadWithNSThreadMethodThree()
    21     {
    22         //开启一条后台线程,自动启动线程,但无法获得线程对象
    23         self.performSelectorInBackground(Selector("run"), withObject: nil);
    24     }
    25 
    26     func createNewThreadWithNSThreadMethodFour()
    27     {
    28         //let thread =  CustomThread.init(target: self, selector:Selector("run"), object: nil)
    29         let thread = CustomThread();
    30         thread.start()
    31     }
    32 
    33     func run()
    34     {
    35         //获得当前执行run方法的线程
    36         let thread = NSThread.currentThread()
    37         print("run--(thread.name)-(thread)");
    38    }
    
    
    三 NSThread线程的状态和线程安全
    
      1)线程的状态
    
        线程的状态:新建-就绪-运行-阻塞-死亡
    
    1      //线程的退出
    2         NSThread.exit()
    3         //线程的休眠1
    4         NSThread.sleepForTimeInterval(2.0)
    5         //线程的休眠2
    6         NSThread.sleepUntilDate(NSDate.init(timeIntervalSinceNow: 3.0))
    
      2)线程安全
    
        说明:多线程访问同一个资源的时候可能会出现数据错乱等安全问题,解决方法是对必要的代码段进行加锁。
    
        注意:在OC中加互斥锁使用@synchronized(self) {},在Swift可以使用objc_sync_enter(self)和objc_sync_exit(self)方法,注意这两个方法必须成对使用,把要加锁的代码放在中间
    
     1 class ViewController: UIViewController {
     2 
     3     //设置总票数为100张
     4     var totalTickets = 100
     5 
     6     override func viewDidLoad() {
     7         super.viewDidLoad()
     8 
     9         //多线程访问资源加锁
    10         //创建三条线程分别代表售票员A、售票员B、售票员C
    11         let thread01 = NSThread.init(target: self, selector:Selector("saleTickect"), object: nil)
    12         let thread02 = NSThread.init(target: self, selector: Selector("saleTickect"), object: nil);
    13         let thread03 = NSThread.init(target: self, selector: Selector("saleTickect"), object: nil);
    14 
    15         //设置线程的名称
    16         thread01.name = "售票员A"
    17         thread02.name = "售票员B"
    18         thread03.name = "售票员C"
    19 
    20         //开启线程
    21         thread01.start()
    22         thread02.start()
    23         thread03.start()
    24 
    25     }
    26 
    27     //模拟售票的函数
    28     func saleTickect()
    29     {
    30         while(true)
    31         {
    32             //加互斥锁
    33             /*
    34             * 1)同OC中的@synchronized(self) {}
    35             * 2)objc_sync_enter(self)和objc_sync_exit(self)必须成对使用,把要加锁的代码放在中间
    36             */
    37 
    38             objc_sync_enter(self)
    39 
    40             //检查是否有余票,如果有则卖出去一张
    41             let temp = totalTickets
    42             for var i=0;i<100000;i++
    43             {
    44                 //空的for循环,模拟延迟
    45             }
    46 
    47             if(temp>0)
    48             {
    49                 totalTickets = temp - 1
    50                 print("(NSThread.currentThread().name)卖出去了一张票,还剩(totalTickets)")
    51             }else
    52             {
    53                 print("(NSThread.currentThread().name)发现票已经卖完了")
    54                 break;
    55             }
    56             
    57             objc_sync_exit(self)
    58         }
    59         
    60     }
    61     
    62 }
    
    三 NSThread线程间通信
    
      1)说明
    
        所谓线程间通信,即如何从一个线程进入到另一个线程继续执行任务或者是传递参数(如从子线程回到主线程)
    
        下面的代码示例演示在主线程中先创建一个子线程下载图片,当图片下载完成后又切换到主线程设置图片的操作。
    
     1 //!!!注意,该案例内部下载图片,发送了http请求需要修改info.plist文件
     2     class ViewController: UIViewController {
     3 
     4     @IBOutlet weak var imageView: UIImageView!
     5 
     6     override func viewDidLoad() {
     7         super.viewDidLoad()
     8 
     9         //程序启动后开子线程下载图片,图片下载完成之后回到主线程设置图片
    10          NSThread.detachNewThreadSelector(Selector("downloadImage"), toTarget: self, withObject: nil)
    11     }
    12 
    13     func downloadImage()
    14     {
    15         //1.获得要下载图片的url
    16         let url = NSURL.init(string: "http://p9.qhimg.com/t014d1bd470cb60ac6e.jpg")
    17 
    18         //2.把url地址指向资源的二进制下载到本地
    19         let imageData = NSData.init(contentsOfURL: url!)
    20 
    21         //3.把二进制数据转换为图片
    22         let image = UIImage.init(data: imageData!);
    23 
    24         //4.打印查看当前线程(应该是在子线程中下载图片)
    25         print("当前线程为(NSThread.currentThread())")
    26 
    27         //5.线程间通信
    28         //方法一
    29         self.performSelectorOnMainThread(Selector("showImage:"), withObject: image, waitUntilDone:true)
    30         //方法二
    31         //imageView.performSelectorOnMainThread(Selector("setImage:"), withObject: image, waitUntilDone:true)
    32     }
    33 
    34     
    35     func showImage(image:UIImage)
    36     {
    37         //设置图片
    38         imageView.image = image
    39 
    40         //打印查看设置图片操作的线程
    41         print("处理UI刷新操作的线程(NSThread.currentThread())")
    42 
    43     }
    44 }
    
  • 相关阅读:
    word设置的密码忘了怎么办?
    Navicat Report Viewer 设置 HTTP 的方法
    如何处理Navicat Report Viewer 报表
    excel密码忘记了怎么办
    Beyond Compare文本比较搜索功能详解
    Popular Cows POJ
    Problem B. Harvest of Apples HDU
    网络流模型整理
    The Shortest Statement CodeForces
    Vasya and Multisets CodeForces
  • 原文地址:https://www.cnblogs.com/Free-Thinker/p/6428827.html
Copyright © 2011-2022 走看看