美文网首页
iOS用NSCondition休眠线程

iOS用NSCondition休眠线程

作者: 呼呼兔 | 来源:发表于2020-05-03 20:38 被阅读0次

记得以前项目中有个需求是,部分接口的调用需要放到非主线程中,并且还有顺序要求。那时NSURLConnection还没废弃,用sendSynchronousRequestGCD实现的,大概如下。

    //创建个串行队列
    dispatch_queue_t queue = dispatch_queue_create("xxxxx", DISPATCH_QUEUE_SERIAL);
    //接口1 加入队列中
    dispatch_async(queue, ^{
        NSData *data = [NSURLConnection sendSynchronousRequest:xxx returningResponse:xx error:xx];
        
    }];
    //接口2 加入队列中
    dispatch_async(queue, ^{
        NSData *data = [NSURLConnection sendSynchronousRequest:xxx returningResponse:xx error:xx];
        
    }];
    ...

但是NSURLConnection换成URLSession后,URLSession中的数据返回都是异步的block和代理,没有同步请求。所以就想到了线程先休眠,等到回调后在停止休眠,返回data。一查使用NSCondition还真能实现这种效果。实现如下。

func testUrl() -> Data? {
    var reData: Data?
    let cond = NSCondition()
    cond.lock()
    URLSession.shared.dataTask(with: URL.init(string: "https://www.baidu.com")!) { (data, resp, error) in
        reData = data
        cond.signal()
    }.resume()
    cond.wait()
    cond.unlock()
    return reData
}
//默认是串行队列
let queue = DispatchQueue.init(label: "jj", attributes: [])
queu.async {
    let data1 = testUrl()
}
queu.async {
    let data2 = testUrl()
}
//这样就能按着顺序调用接口,处理数据。

其实用DispatchGroup也能实现类似的需求。

func testUrl11() -> Data? {
    var reData: Data?
    let group = DispatchGroup()
    group.enter()
    URLSession.shared.dataTask(with: URL.init(string: "https://www.baidu.com")!) { (data, resp, error) in
        reData = data
        group.leave()
    }.resume()
    group.wait()
    return reData
}
queu.async {
    let data3 = testUrl11()
}
queu.async {
    let data4 = testUrl11()
}

注意

  1. 这两个方法,我没有放到项目中使用,所以不确定是否有bug。
  2. 使用NSCondition问题很多。
    • 由于broadcast可以唤醒所有被-wait方法阻塞着的线程。所以在其他地方调用broadcast方法会影响到这里的。
    • 根据苹果官方文档,-signal方法本身就不完全保证是准确的,会存在其他线程没有调用-signal方法,但是被wait的线程依然被唤醒的情况。
    • 就算被wait的线程的唤醒时机没有问题,但是在被wait的线程被唤醒到执行后面代码期间,程序状态可能会发生变化,这也是一个风险项。
  3. 由于这里使用了多线程。所以有必要的情况下一定用NSLock加锁解锁。

参考

相关文章

  • iOS用NSCondition休眠线程

    记得以前项目中有个需求是,部分接口的调用需要放到非主线程中,并且还有顺序要求。那时NSURLConnection还...

  • 线程锁

    探讨iOS开发中各种锁使用NSCondition实现多线程同步 NSCondition是线程同步, 阻塞线程。 取...

  • iOS利用NSCondition唤醒/休眠线程

    简介 想了解一个app启动图显示结束之后展示广告资源的需求。即开启一个子线程获取广告资源,LaunchScreen...

  • iOS同步锁小探

    我测试的iOS同步锁包括@synchronsized、NSLock、NSCondition、NSCondition...

  • iOS NSCondition详解

    iOS NSCondition讲解 1.定义 官方文档:The NSCondition class impleme...

  • iOS-锁-NSCondition&NSConditionLoc

    NSCondition 条件锁,顾名思义,就是满足某些条件才会开锁。NSCondition,可以确保线程仅在满足特...

  • 多线程常用方法2(休眠)

    定义: 所谓的线程休眠就是让线程的速度变慢一点。用sleep方法。 sleep方法上还有一个异常。如果打断休眠就会...

  • 多线程之(线程休眠)

    线程休眠 线程休眠,是通过调用线程的sleep()方法来实现。即让线程当前的状态转换为休眠状态(阻塞状态)。我们可...

  • 使用NSCondition实现不同线程等待唤醒

    NSCondition : 一个线程可能需要等待其它线程返回结果.本例中,使用 condition 对"生产","...

  • NSRunLoop

    NSRunLoop--NSRunLoop是IOS消息机制的处理模式,控制NSRunLoop里面线程的执行和休眠,在...

网友评论

      本文标题:iOS用NSCondition休眠线程

      本文链接:https://www.haomeiwen.com/subject/txdjghtx.html