iOS --- 线程安全之semaphore

来源:互联网 发布:c语言中float取值范围 编辑:程序博客网 时间:2024/06/07 01:44

dispatch_semaphore是GCD中常见的同步方式, 相关方法有三个: dispatch_semaphore_create, dispatch_semaphore_wait, dispatch_semaphore_signal.

dispatch_semaphore的使用方式

// will barrier the UI.let signal: dispatch_semaphore_t = dispatch_semaphore_create(0)dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), {    print("execution inside the block ...")    sleep(10)    dispatch_semaphore_signal(signal)})print("execution outside the block, waiting ...")dispatch_semaphore_wait(signal, DISPATCH_TIME_FOREVER)print("execution outside the block, ok ...")

运行结果:
print(“execution outside the block, ok …”)这句代码会在信号量signal发出之后执行, 即dispatch_semaphore_signal(signal)执行完毕, 才有机会执行.
因此, 可以用来进行一些同步操作.
dispatch_semaphore_create(0)方法介绍一个long类型的参数, 返回一个dispatch_semaphore_t类型的信号量且值为0.
dispatch_semaphore_wait(signal, DISPATCH_TIME_FOREVER)方法检测signal信号量的值, 若值为0, 则该方法会阻塞当前线程并等待. 第二个参数即为等待时间.
等待期间, 信号量不为0, 则该方法所在的线程获取了信号量, 继续执行.
因此, 如果使用dispatch_semaphore_wait(signal, dispatch_time(DISPATCH_TIME_NOW, (Int64)(NSEC_PER_SEC * 2)))则会等待2s时间, 超时则信号量失效, 释放对线程的阻塞.
dispatch_semaphore_signal(signal)使信号量signal加1.

同步获取网络请求的内容

如下方法可以同步获取网络请求中的JSON对象:

/** Get Synchronous JSON response from an URL using Semaphore. - parameter urlString:         url - parameter completionHandler: completionHandler to execute after getting response - returns: JSON format object */public class func cs_getJSONObjectSynchronously(urlString: String, completionHandler: (jsonObject: AnyObject) -> Void) -> AnyObject {    var jsonObject: AnyObject!    let request = NSURLRequest(URL: NSURL(string: urlString)!)    let semaphore = dispatch_semaphore_create(0)    let dataTask = NSURLSession.sharedSession().dataTaskWithRequest(request)    { (data, response, error) in        do {            jsonObject = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers)            completionHandler(jsonObject: jsonObject)            dispatch_semaphore_signal(semaphore)        } catch {        }    }    dataTask.resume()    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)    return jsonObject}

同步获取指定APP在AppStore中的当前版本

有了以上的了解, 我们可以封装一个方法来同步获取指定APP在AppStore中的当前版本:

/** current App Version released in AppStore - parameter appId: appId in AppStore - returns: lastest appVersion in AppStore */func cs_appVersionInAppStore(appId: String) -> String {    var appVersion = ""    let url = "https://itunes.apple.com/lookup?id=\(appId)"    let request = NSURLRequest(URL: NSURL(string: url)!)    let semaphore = dispatch_semaphore_create(0)    let dataTask = NSURLSession.sharedSession().dataTaskWithRequest(request)    { (data, response, error) in        do {            let jsonData = try NSJSONSerialization.JSONObjectWithData(data!, options: .MutableContainers)            if let results = jsonData["results"]! {                assert(results.count != 0, "results should not be null")                appVersion = results.firstObject!?["version"]! as! String            }            dispatch_semaphore_signal(semaphore)        } catch {        }    }    dataTask.resume()    dispatch_semaphore_wait(semaphore, DISPATCH_TIME_FOREVER)    return appVersion}

Demo:

Demo请参考:
iOS-MultiThread,
同步获取指定APP在AppStore中的当前版本.

0 0
原创粉丝点击