• 完整具体解释GCD系列(二)dispatch_after;dispatch_apply;dispatch_once


    原创Blog,转载请注明出处

    本文阅读的过程中,如有概念不懂,请參照前专栏中之前的文章,假设还有疑惑,请留言。

    这是我关于GCD专栏的地址

    http://blog.csdn.net/column/details/swift-gcd.html

    本教涵盖的内容
    一、dispatch_after
    二、dispatch_apply 
    三、dispatch_once


    一、dispatch_after
    功能:延迟一段时间把一项任务提交到队列中运行,返回之后就不能取消
    经常使用来在在主队列上延迟运行一项任务
    函数原型
    func dispatch_after(_ when: dispatch_time_t,
                      _ queue: dispatch_queue_t!,
                      _ block: dispatch_block_t!)
    參数
            when	过了多久运行的时间间隔
    	queue	提交到的队列
    	block	运行的任务


    比如:能够利用dispatch_after写一个自己用的Delay函数,delay一段时间在主线程上运行一段代码
    func hwcDelay(delay:Double, closure:()->()) {
        dispatch_after(
            dispatch_time(
                DISPATCH_TIME_NOW,
                Int64(delay * Double(NSEC_PER_SEC))
            ),
            dispatch_get_main_queue(), closure)
    }

    仅仅须要这样使用
    hwcDelay(0.5){
    //Do everything you want
    }
    比方,当用户的应用不满足某些我们App须要的条件时候(比如,我们的App须要蓝牙打开),然后在APP启动的时候測到蓝牙Off后,应当给用户一个提示。在view加载完毕后,延迟给用户一个提示,也能够给这个提示加入一些动画,要比view在加载完毕直接显示提示要有好的多。
    举例
    在viewLoad后,延迟1s,提示一个alertview
    class ViewController: UIViewController{    
        func hwcDelay(delay:Double, closure:()->()) {
        dispatch_after(
            dispatch_time(
                DISPATCH_TIME_NOW,
                Int64(delay * Double(NSEC_PER_SEC))
            ),
            dispatch_get_main_queue(), closure)
    }  
        override func viewDidLoad(){    
            super.viewDidLoad()    
            hwcDelay(1.0){
    		var alertview = UIAlertView(title:"Dispatch_after",message:"Message",delegate:self,cancelButtonTitle:"OK")
    		alertview.show()
    	}          
        }    
        override func didReceiveMemoryWarning(){    
            super.didReceiveMemoryWarning()    
        }    
    } 

    二、dispatch_apply
    功能:把一项任务提交到队列中多次运行,详细是并行运行还是串行运行由队列本身决定.注意,dispatch_apply不会立马返回,在运行完成后才会返回,是同步的调用。
    func dispatch_apply(_ iterations: UInt,
                      _ queue: dispatch_queue_t!,
                      _ block: ((UInt) -> Void)!)
    參数
    iterations	运行的次数
    	queue		提交到的队列
    	block		运行的任务

    那么,何时使用这个函数呢?从它的功能不难看出,假设我们能够把不相关的循环提交到后台线程并行运行,而且循环任务调度到后台运行的效率提高,能抵消掉队列调度本身的开销,那么效率会显著提高。

    举例
    比方我有一个数组,存储了一系列对象,初始化的时候,这些对象都要调用一次某函数来进行相关的计算。这些计算相互没有影响。这时,我们就能够用dispatch_apply来使用异步队列来初始化.这里把这样的情况进行简化
    class ViewController: UIViewController{    
        var hwcarray = ["hello","hwc","hellohwc"]
        override func viewDidLoad(){    
            super.viewDidLoad()    
            dispatch_apply(3,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)){
    		(index:UInt) -> () in
    		var expObject = self.hwcarray[Int(index)] as NSString
    		NSLog("%d",expObject.length)
    	}  
    	NSLog("Dispatch_after is over")     
        }    
        override func didReceiveMemoryWarning(){    
            super.didReceiveMemoryWarning()    
        }    
    } 
    能够看到,输出是
    3
    5
    8
    dispatch_after is over
    因为这样会堵塞主线程,而下文又与dispatch_apply的运行结果无关,所以能够在异步队列中掉dispatch_apply,然后运行完毕后进行通知
    class ViewController: UIViewController{    
        var hwcarray = ["hello","hwc","hellohwc"]
        override func viewDidLoad(){ 
            super.viewDidLoad()
    	dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)){
    	 dispatch_apply(3,dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT,0)){
    		(index:UInt) -> () in
    		var expObject = self.hwcarray[Int(index)] as NSString
    		NSLog("%d",expObject.length)
    	 }
    	 NSLog("Dispatch_after in global queue is over")  
    	}    
           
    	NSLog("Dispatch_after in main queue is over")     
        }    
        override func didReceiveMemoryWarning(){    
            super.didReceiveMemoryWarning()    
        }    
    }
    这样输出为

    8
    Dispatch_after in main queue is over
    3
    5
    Dispatch_after in global queue is over
    能够看到,相对主队列(主线程)是异步的,在global队列中是并行运行的


    三、dispatch_once
    功能:保证在APP执行期间,block中的代码仅仅执行一次
    func dispatch_once(_ predicate: UnsafeMutablePointer<dispatch_once_t>,
                     _ block: dispatch_block_t!)
    參数
    predicate 用来推断提交的block是否运行完毕
    block 运行一次的任务
    dispatch_once的经典有用场景是单例
    单例代码:
    class hwcSingleton {
         var testVariable:Int!
         func print(){
    	testVariable = testVariable + 1
    	println(testVariable)
    	}
        class var sharedObject: hwcSingleton {
            struct StaticStruct {
                static var predicate : dispatch_once_t = 0
                static var instance : hwcSingleton? = nil
            }
            dispatch_once(&StaticStruct.predicate) {
                StaticStruct.instance = hwcSingleton()
    	   StaticStruct.instance?.testVariable = 10
            }
            return StaticStruct.instance!
        }
    }

    当然也能够在多线程环境下,保证一段代码仅仅运行一次。
  • 相关阅读:
    类似qq弹窗,自动消失
    词法分析实验报告
    编译原理
    开发中遇到的杂七杂八
    Gradle+Jetty实现静态资源的热部署
    Eclipse中进行Gradle+Jetty部署的web项目的断点调试
    俳句与短歌收藏
    影评收藏
    诗歌与词曲收藏
    歌词收藏
  • 原文地址:https://www.cnblogs.com/mfrbuaa/p/4469710.html
Copyright © 2020-2023  润新知