前提
我们都知道宇宙中有好数字和坏数字。
我有以下同步功能

func isGood(number:Int) -> Bool {
    // synchronous connection
    // ...
    // returns a Bool
}

当然,我这里不提供秘密实现,但是您应该知道它执行同步的Internet连接,并且它确实返回
true:if theIntreceived as param is a“good number”
否则
问题
现在,给定从0到99的100个整数,我想知道它们中是否至少有51个是好数字。
同步方法
我可以写这样的东西。
func majorityIsGood() -> Bool {
    var count = 0
    for i in 0...99 {
        if isGood(i) {
            count++
            if count > 50 {
                return true
            }
        }
    }
    return false
}

但是对false执行100次同步调用(在最坏的情况下)需要太多时间。我需要尽快得到答案。
异步方法
我想要像这样的东西
func majorityIsGood(completion:(good:Bool) -> ()) {
    var goodNums = 0
    var badNums = 0
    var resultFound = false

    for i in 0...99 {
        dispatch_async(DISPATCH_QUEUE_CONCURRENT) {

            let isGood = isGood(i)

            // lineA
            // begin lock on (resultFound)
            if !resultFound {
                if isGood {
                    goodNums++
                } else {
                    badNums++
                }
                if goodNums > 50 || badNums >= 50 {
                    resultFound = true
                    completion(good: goodNums > 50)
                }
            }
            // end lock on (resultFound)
            // lineB
        }
    }
}

问题
如何保证在swift中的isGoodlineA之间同步访问代码块?
最后,一旦得到结果,是否可以终止仍在处理的并发闭包?
提前谢谢。

最佳答案

serial queue可用于同步对特定资源的访问。
我不确定。如果存在终止正在调度的并发操作的方法。但是,如果你只是想阻止他们。请看一下“取消”。
这是密码

func majorityIsGood( completion: ((good:Bool) -> Void) ) {

    var goodNums = 0
    var badNums = 0
    var resultFound = false

    let serialQueue = dispatch_queue_create("com.unique.myQueue", DISPATCH_QUEUE_SERIAL)

    for i in 0...99 {
        dispatch_async(DISPATCH_QUEUE_CONCURRENT) {

            let _isGood = isGood(i)

            // lineA
            dispatch_async(serialQueue){
                if !resultFound {
                    if _isGood {
                        goodNums++
                    } else {
                        badNums++
                    }
                    if goodNums > 50 || badNums >= 50 {
                        resultFound = true
                        completion(good: goodNums > 50)
                    }
                }
            }
            // lineB
        }
    }
}

09-16 03:57