swift判断是不是主线程_swift 判断当前是否为主线程 - CSDN
精华内容
参与话题
  • 一 说明 本文涉及代码可以从... 二 NSThread的基本使用和创建  1)基本用法(主线程|当前线程) 1 //1.获得执行该方法的当前线程 2 let currentThread = NSThread.currentThread() 3

    一 说明

    本文涉及代码可以从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 }
    复制代码

    展开全文
  • swift3.0 中如何在主线程中刷新UI

    万次阅读 2016-07-31 12:18:25
    类似OC 中的GCD,只是调用方法不同,更方便,如下代码,功能为刷新tableview;   DispatchQueue.main.async(execute: {  self.listTableview.reloadData() })

    类似OC 中的GCD,只是调用方法不同,更方便,如下代码,功能为刷新tableview;

     

    DispatchQueue.main.async(execute: {

        self.listTableview.reloadData()

    })

    展开全文
  • 如何判断当前线程是主线程

    千次阅读 2019-03-14 12:08:16
    在开发应用程序时,我们异步请求数据处理后,需要回到主线程刷新UI,一般情况下直接通过以下方式异步回到主线程: dispatch_async(dispatch_get_main_queue(), ^{ // 主线程刷新UI操作 }); 看过SDWebImage...

    在开发应用程序时,我们异步请求数据处理后,需要回到主线程刷新UI,一般情况下直接通过以下方式异步回到主线程: 

      dispatch_async(dispatch_get_main_queue(), ^{
            //  主线程刷新UI操作
    
        }); 


    看过SDWebImage源码的应该看过它里面有这样一个宏:

    #ifndef dispatch_main_async_safe
    #define dispatch_main_async_safe(block)\
        if (strcmp(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL), dispatch_queue_get_label(dispatch_get_main_queue())) == 0) {\
            block();\
        } else {\
            dispatch_async(dispatch_get_main_queue(), block);\
        }
    #endif 


    其中通过如下一句代码来判断当前是否是在主线程

    strcmp(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL), dispatch_queue_get_label(dispatch_get_main_queue())) == 0


     
    上述判断用到了strcmp函数和dispatch_queue_get_label函数

    strcmp(字符串1,字符串2):C语言中的函数,用于比较2个字符串的大小

    比较规则:对两个字符串自左至右逐个字符相比(按ASCII码值大小比较),直到出现不同的字符或遇到‘\0’为止。如果全部字符相同,则认为相等;若出现不相同的字符,则以第一个不相同的字符的比较结果为准

    返回值: 
    (1)字符串1=字符串2,返回0 
    (2)字符串1>字符串2,返回一个正整数 
    (3)字符串1<字符串2,返回一个负整数。

    dispatch_queue_get_label:获取指定队列的label名称,返回值是C语言的字符串

    如果没有指定队列的名称,就返回NULL,如果传入的是DISPATCH_CURRENT_QUEUE_LABEL则返回当前队列的label名称

    上述方法的思路是通过判断当前队列是否是主队列来判断是否在主线程。

    既然如此,我们是否可以直接通过GCD提供的方法dispatch_get_current_queue()获取当前队列来判断是不是主队列?

    dispatch_get_current_queue()在iOS 6.0时已经废弃了,弃用的原因在于当获取的目标队列正好是当前队列时会同步阻塞导致死锁。点击查看详细讲解

    还有一个比较常见的,判断是否是主线程的方法

       

    BOOL isMain = [NSThread isMainThread];


     
    这个方法在大部分情况下是有效的,但是有些情况下会出现问题失效情景, 
    原因在于下面这句话:

    MapKit: It's not safe to call MKMapView's addOverlay on a non-main-queue, even if it is executed on the main thread #7053
     
    即在非主队列即使是在主线程调用MKMapView’s addOverlay的方法也是不安全的。因为上述方法只会检查当前是否在主线程,而不去判断是否在主队列

    综上所述:

    1、每个应用程序只有一个主线程,主线程上可能有很多不同的队列在运行 
    2、主队列一定在主线程运行,非主队列不一定不在主线程 
    3、有些库的运行不但依赖主线程,更是依赖主队列,例如:MapKit 

    展开全文
  • iOS 判断是否在主线程

    千次阅读 2019-04-18 11:27:13
    有时候我们需要验证当前在哪个线程,如下: if (strcmp(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL), dispatch_queue_get_label(dispatch_get_main_queue())) == 0) { // do something in main ...

    有时候我们需要验证当前在哪个线程,如下:

     if (strcmp(dispatch_queue_get_label(DISPATCH_CURRENT_QUEUE_LABEL), dispatch_queue_get_label(dispatch_get_main_queue())) == 0) {
                // do something in main thread
                NSLog(@"--main thread");
            } else {
                // do something in other thread
                NSLog(@"--other thread");
                
            }

     

    展开全文
  • ODUIThreadGuard一个保安帮助你检查做UI更改是否不在主线程
  • IOS中如何切换到主线程工作

    千次阅读 2016-03-13 18:27:44
    Swift Version dispatch_async(dispatch_get_main_queue(), { // code here }) Objective-C Version dispatch_async(dispatch_get_main_queue(), ^{ // code here });
  • 1,Swift继续使用Object-C原有的一套线程,包括三种多线程编程技术:(1)NSThread(2)Cocoa NSOperation(NSOperation和NSOperationQueue)(3)Grand Central Dispath(GCD)2,本文着重介绍Grand Central ...
  • 第一题(主线程只会执行主队列的任务吗?) letkey=DispatchSpecificKey() DispatchQueue.main.setSpecific(key:key,value:"main") funclog(){ debugPrint("mainthread:\(Thread.isMainThread)&...
  • 对iOS代码中分发到主线程的代码进行封装成C/C++方法
  • 在开发 iOS 的时候,我们都知道 UI 相关的操作必须放在主线程,但是只要放在主线程就安全了么? 答案是否定的。在苹果的 MapKit 框架中,一个名为 addOverlay 的方法不仅要放在主线程中,而且必须放在主队列中。苹果...
  • swift中的值类型 在swift中不同于oc,数组和字典等都被定义为了值类型,而与之对应的类属于引用类型。当然值类型还包括结构体和枚举。值类型有一个优点就是线程安全,本篇也只讨论其线程安全的问题。 一个有趣的例子...
  • swift ~ 2020年 swift面试题

    千次阅读 2020-05-27 19:37:10
    Swift是苹果于2014年WWDC(苹果开发者大会)发布的新开发语言,可与Objective-C共同运行于MAC OS和iOS平台,用于搭建基于苹果平台的应用程序。 2、举例说明Swift里面有哪些是 Objective-C中没有的? Swift...
  • 主线程卡顿监控,通过子线程监测主线程的 runLoop,判断两个区域状态之间的耗时是否达到一定阈值。 FPS监控。要保持流畅的UI交互,App 刷新率应该当努力保持在 60fps。监控实现原理比较简单,通过记录两次刷新时间...
  • HealthKit Swift 教程: 开始

    千次阅读 2017-10-24 14:09:46
    原文:HealthKit Tutorial with Swift: Workouts 作者:Ted Bendixson 译者:kmyhy 更新说明:本教程由 Ted Bendixson 升级至 Swift 4、Xcode 9 及 iOS 11。原教程作者是Ernesto García。 HealthKit 从 iOS ...
  • Instruments Swift教程:开始 原文:Instruments Tutorial with Swift: Getting Started 作者:Nicholas Sakaimbo 译者:kmyhy 更新说明:本教程由 Nicholas Sakaimbo 升级至 iOS 11\Xcode 9\Swift 4。...
  • Swift中利用NSURLConnection进行同步异步下载(实例解析)

    千次阅读 多人点赞 2014-11-11 08:27:56
    简单来讲,同步就是函数或者闭包(objective c中的block)执行完毕才能返回。异步是立刻返回,然后异步执行的动作结束后,再进行回调。 二、同步下载 同步下载: class func sendSynchronousRequest(_ request: ...
  • Swift的多线程技术其实和Objective-C没有区别。Thread是三种正常程序员会使用的多线程中最轻量级的,每一个Thread对象代表着一个线程,但是需要自己管理线程的生命周期和线程的同步。线程同步对数据的加锁会有一定的...
  • swift杂乱整理

    2018-07-26 09:44:12
    001--swift简史小视频 002--Playground体验 003--常量&amp;变量 一、swift简史 1、介绍 swift是苹果公司于2014年推出用于撰写OS和iOS应用程序的语言。它由苹果开发者工具部门总监“克里斯.拉特纳”在2010年...
1 2 3 4 5 ... 20
收藏数 1,220
精华内容 488
关键字:

swift判断是不是主线程